Retirado do artigo Miller et al. (2019). Distance sampling in R. Journal of Statistical Sofware 89(1)

dados_completos |> 
  group_by(
    uc_name,
    ea_name
  ) |> 
  filter(day_effort == max(day_effort))  |> 
  drop_na(distance) |> 
  ungroup()
dados_completos |> 
  filter(
    uc_name == "Resex Tapajos-Arapiuns",
    sp_name == "Dasyprocta croconota"
  ) |> 
  datatable(filter = list(position = "top"))

Formatação do conjunto de dados

Variáveis necessárias para o data.frame:

Transectos que foram amostrados, mas que não tiveram observações (n = 0) devem ser incluídos no conjunto de dados com NA nas observações de distância e qualquer outra covariael para a qual não se tenha observação.

# cutia_tap_arap |> 
#   complete(Region.Label, Sample.Label, sp_name) |> 
#   datatable(filter = list(position = "top"))

Jogar a imputacao de NAs pra dentro da funcao carregar dados completos.

Determinando a distância para truncar os dados

# desenha o grafico com a distribuicao de distancias perpendiculares
cutia_tap_arap |> 
  filter(distance >= 1,
         distance <= 14) |> 
  plotar_distribuicao_distancia_interativo()
summary(cutia_tap_arap$distance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  0.000   1.550   6.000   7.187  10.000  50.000 

Ajustando funções de detecção no R

Cutias da Resex Tapajós-Arapiuns para diferentes distâncias de truncamento

Half-Normal sem termos de ajuste e com termos de ajuste Cosseno e Polinomial de Hermite

Ajustando um modelo ao dados das cutias Dasyprocta croconota, configurando uma distância limite de 20m e usando Half-normal como key function usando o argumento key, sem termo de ajuste.

# Key function - Half-normal 
cutia_tap_arap_hn <- purrr::map(
  dist_truncamento,
  \(.x) ajuste_modelos_distance_hn(
    cutia_tap_arap_filtrado, 
    truncamento = .x
  )
  )
Fitting half-normal key function
AIC= 4346.405
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 4346.405
Fitting half-normal key function with cosine(2) adjustments
AIC= 4338.754
Fitting half-normal key function with cosine(2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4328.058
Fitting half-normal key function with cosine(2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4322.361
Fitting half-normal key function with cosine(2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4316.235
Fitting half-normal key function with cosine(2,3,4,5,6) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4361.776

Half-normal key function with cosine(2,3,4,5) adjustments selected.
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 4346.405
Fitting half-normal key function with Hermite(4) adjustments
AIC= 4331.217
Fitting half-normal key function with Hermite(4,6) adjustments
AIC= 4333.267

Half-normal key function with Hermite(4) adjustments selected.
Fitting half-normal key function
AIC= 3893.364
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 3893.364
Fitting half-normal key function with cosine(2) adjustments
Warning: First partial hessian is singular; using second-partial hessian
Warning: Detection function is not weakly monotonic!Warning: Detection function is not strictly monotonic!Warning: Detection function is greater than 1 at some distancesWarning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Half-normal key function selected.
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 3893.364
Fitting half-normal key function with Hermite(4) adjustments
Warning: First partial hessian is singular; using second-partial hessian
AIC= 3895.364

Half-normal key function selected.
Fitting half-normal key function
AIC= 3262.461
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 3262.461
Fitting half-normal key function with cosine(2) adjustments
Warning: First partial hessian is singular; using second-partial hessian
Warning: Detection function is not weakly monotonic!Warning: Detection function is not strictly monotonic!Warning: Detection function is greater than 1 at some distancesWarning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Half-normal key function selected.
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 3262.461
Fitting half-normal key function with Hermite(4) adjustments
AIC= 3264.461

Half-normal key function selected.
Fitting half-normal key function
AIC= 1803.913
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 1803.913
Fitting half-normal key function with cosine(2) adjustments
Warning: First partial hessian is singular; using second-partial hessian
Warning: Detection function is not weakly monotonic!Warning: Detection function is not strictly monotonic!Warning: Detection function is greater than 1 at some distancesWarning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Half-normal key function selected.
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 1803.913
Fitting half-normal key function with Hermite(4) adjustments
Warning: First partial hessian is singular; using second-partial hessian
AIC= 1899.845

Half-normal key function selected.
cutia_tap_arap_hn
$`20 metros`
$`20 metros`$`Sem termo`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 2310.909 

$`20 metros`$Cosseno

Distance sampling analysis object

Detection function:
 Half-normal key function with cosine adjustment terms of order 2,3,4,5 

Estimated abundance in covered region: 3280.45 

$`20 metros`$`Hermite polinomial`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 2310.909 


$`15 metros`
$`15 metros`$`Sem termo`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 1767.642 

$`15 metros`$Cosseno

Distance sampling analysis object

Detection function:
 Half-normal key function with cosine adjustment terms of order 2,3 

Estimated abundance in covered region: 2320.64 

$`15 metros`$`Hermite polinomial`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 1767.642 


$`10 metros`
$`10 metros`$`Sem termo`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 1154.866 

$`10 metros`$Cosseno

Distance sampling analysis object

Detection function:
 Half-normal key function with cosine adjustment terms of order 2,3,4 

Estimated abundance in covered region: 2010.188 

$`10 metros`$`Hermite polinomial`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 1154.866 


$`5 metros`
$`5 metros`$`Sem termo`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 806.2075 

$`5 metros`$Cosseno

Distance sampling analysis object

Detection function:
 Half-normal key function with cosine adjustment terms of order 2,3,4,5 

Estimated abundance in covered region: 1892.596 

$`5 metros`$`Hermite polinomial`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 806.2075 

Hazard-Rate sem termos de ajuste e com termos de ajuste Cosseno e Polinomial de Hermite

Ajustando um modelo ao dados da cutia Dasyprocta croconota, configurando uma distância limite de 20m e usando Hazard rate como key function usando o argumento key.

# ajustando a função de detecção para uma distancia de truncamento de 20, 15, 10 e 5 metros
# Key function - Hazard-rate
cutia_tap_arap_hr <- purrr::map(
  dist_truncamento,
  \(.x) ajuste_modelos_distance_hr(
    cutia_tap_arap_filtrado, 
    truncamento = .x
  )
  )
Fitting hazard-rate key function
AIC= 4302.674
Starting AIC adjustment term selection.
Fitting hazard-rate key function
AIC= 4302.674
Fitting hazard-rate key function with cosine(2) adjustments
AIC= 4304.745

Hazard-rate key function selected.
Starting AIC adjustment term selection.
Fitting hazard-rate key function
AIC= 4302.674
Fitting hazard-rate key function with simple polynomial(4) adjustments
AIC= 4304.726

Hazard-rate key function selected.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 3892.732
Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 3892.732
Fitting hazard-rate key function with cosine(2) adjustments
Warning: First partial hessian is singular; using second-partial hessian
Warning: Detection function is not weakly monotonic!Warning: Detection function is not strictly monotonic!Warning: Detection function is greater than 1 at some distancesWarning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 3892.732
Fitting hazard-rate key function with simple polynomial(4) adjustments
Warning: First partial hessian is singular; using second-partial hessian
AIC= 3897.364

Hazard-rate key function selected.
Fitting hazard-rate key function
AIC= 3262.081
Starting AIC adjustment term selection.
Fitting hazard-rate key function
AIC= 3262.081
Fitting hazard-rate key function with cosine(2) adjustments
Warning: First partial hessian is singular; using second-partial hessian
Warning: Detection function is not weakly monotonic!Warning: Detection function is not strictly monotonic!Warning: Detection function is greater than 1 at some distancesWarning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Starting AIC adjustment term selection.
Fitting hazard-rate key function
AIC= 3262.081
Fitting hazard-rate key function with simple polynomial(4) adjustments
Warning: First partial hessian is singular; using second-partial hessian
AIC= 3266.461

Hazard-rate key function selected.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 1804.357
Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 1804.357
Fitting hazard-rate key function with cosine(2) adjustments
Warning: First partial hessian is singular; using second-partial hessian
Warning: Detection function is not weakly monotonic!Warning: Detection function is not strictly monotonic!Warning: Detection function is greater than 1 at some distancesWarning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 1804.357
Fitting hazard-rate key function with simple polynomial(4) adjustments
Warning: First partial hessian is singular; using second-partial hessian
AIC= 1807.913

Hazard-rate key function selected.

Uniform sem termos de ajuste e com termos de ajuste Cosseno e Polinomial de Hermite

Ajustando um modelo ao dados das cutias Dasyprocta croconota, configurando uma distância limite de 20m e usando Uniform como key function usando o argumento key, sem termo de ajuste.

# ajustando a função de detecção para uma distancia de truncamento de 20, 15, 10 e 5 metros
# Key function - Uniform
cutia_tap_arap_unif <- purrr::map(
  dist_truncamento,
  \(.x) ajuste_modelos_distance_unif(
    cutia_tap_arap, 
    truncamento = .x
  )
)
Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 5995.938
Fitting uniform key function with cosine(1) adjustments
AIC= 5796.939
Fitting uniform key function with cosine(1,2) adjustments
AIC= 5796.796
Fitting uniform key function with cosine(1,2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5729.113
Fitting uniform key function with cosine(1,2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5729.808

Uniform key function with cosine(1,2,3) adjustments selected.
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 5995.938
Fitting uniform key function with simple polynomial(2) adjustments
AIC= 5799.151
Fitting uniform key function with simple polynomial(2,4) adjustments
AIC= 5796.184
Fitting uniform key function with simple polynomial(2,4,6) adjustments
AIC= 5791.29
Fitting uniform key function with simple polynomial(2,4,6,8) adjustments
AIC= 5788.217
Fitting uniform key function with simple polynomial(2,4,6,8,10) adjustments
AIC= 5783.105
Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 5432.006
Fitting uniform key function with cosine(1) adjustments
AIC= 5340.635
Fitting uniform key function with cosine(1,2) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5319.03
Fitting uniform key function with cosine(1,2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5282.176
Fitting uniform key function with cosine(1,2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5271.725
Fitting uniform key function with cosine(1,2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5213.714
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 5432.006
Fitting uniform key function with simple polynomial(2) adjustments
AIC= 5366.091
Fitting uniform key function with simple polynomial(2,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5346.537
Fitting uniform key function with simple polynomial(2,4,6) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5338.476
Fitting uniform key function with simple polynomial(2,4,6,8) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5332.686
Fitting uniform key function with simple polynomial(2,4,6,8,10) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5326.193
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 4688.063
Fitting uniform key function with cosine(1) adjustments
AIC= 4647.342
Fitting uniform key function with cosine(1,2) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4617.841
Fitting uniform key function with cosine(1,2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4579.748
Fitting uniform key function with cosine(1,2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4551.3
Fitting uniform key function with cosine(1,2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4523.924
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 4688.063
Fitting uniform key function with simple polynomial(2) adjustments
AIC= 4680.313
Fitting uniform key function with simple polynomial(2,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4651.715
Fitting uniform key function with simple polynomial(2,4,6) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4637.792
Fitting uniform key function with simple polynomial(2,4,6,8) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4631.554
Fitting uniform key function with simple polynomial(2,4,6,8,10) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4622.947
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 3008.377
Fitting uniform key function with cosine(1) adjustments
AIC= 2949.701
Fitting uniform key function with cosine(1,2) adjustments
Warning: Detection function is not strictly monotonic!AIC= 2910.157
Fitting uniform key function with cosine(1,2,3) adjustments
AIC= 2845.858
Fitting uniform key function with cosine(1,2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 2801.709
Fitting uniform key function with cosine(1,2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 2744.89
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 3008.377
Fitting uniform key function with simple polynomial(2) adjustments
AIC= 2981.459
Fitting uniform key function with simple polynomial(2,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 2956.964
Fitting uniform key function with simple polynomial(2,4,6) adjustments
Warning: Detection function is not strictly monotonic!AIC= 2942.061
Fitting uniform key function with simple polynomial(2,4,6,8) adjustments
Warning: Detection function is not strictly monotonic!AIC= 2929.72
Fitting uniform key function with simple polynomial(2,4,6,8,10) adjustments
Warning: Detection function is not strictly monotonic!AIC= 2917.584
Warning: Detection function is not strictly monotonic!
Seleção de modelos
summarize_ds_models(
  cutia_tap_arap_hn$`14 metros`$`Sem termo`,
cutia_tap_arap_hn$`14 metros`$Cosseno,
  cutia_tap_arap_hn$`14 metros`$`Hermite polinomial`,
cutia_tap_arap_hr$`14 metros`$`Sem termo`,
cutia_tap_arap_hr$`14 metros`$Cosseno,
cutia_tap_arap_hr$`14 metros`$`Polinomial simples`,
cutia_tap_arap_unif$`14 metros`$Cosseno,
cutia_tap_arap_unif$`14 metros`$`Polinomial simples`
)
summarize_ds_models(
  cutia_tap_arap_hn$`12 metros`$`Sem termo`,
cutia_tap_arap_hn$`12 metros`$Cosseno,
  cutia_tap_arap_hn$`12 metros`$`Hermite polinomial`,
cutia_tap_arap_hr$`12 metros`$`Sem termo`,
cutia_tap_arap_hr$`12 metros`$Cosseno,
cutia_tap_arap_hr$`12 metros`$`Polinomial simples`,
cutia_tap_arap_unif$`12 metros`$Cosseno,
cutia_tap_arap_unif$`12 metros`$`Polinomial simples`
)
summarize_ds_models(
  cutia_tap_arap_hn$`10 metros`$`Sem termo`,
cutia_tap_arap_hn$`10 metros`$Cosseno,
  cutia_tap_arap_hn$`10 metros`$`Hermite polinomial`,
cutia_tap_arap_hr$`10 metros`$`Sem termo`,
cutia_tap_arap_hr$`10 metros`$Cosseno,
cutia_tap_arap_hr$`10 metros`$`Polinomial simples`,
cutia_tap_arap_unif$`10 metros`$Cosseno,
cutia_tap_arap_unif$`10 metros`$`Polinomial simples`
)
summarize_ds_models(
  cutia_tap_arap_hn$`7 metros`$`Sem termo`,
cutia_tap_arap_hn$`7 metros`$Cosseno,
  cutia_tap_arap_hn$`7 metros`$`Hermite polinomial`,
cutia_tap_arap_hr$`7 metros`$`Sem termo`,
cutia_tap_arap_hr$`7 metros`$Cosseno,
cutia_tap_arap_hr$`7 metros`$`Polinomial simples`,
cutia_tap_arap_unif$`7 metros`$Cosseno,
cutia_tap_arap_unif$`7 metros`$`Polinomial simples`
)

Resumir o resultado dos modelos

O que tem que ter?

Os gráficos (probabilidade de detecção pela distância, com a curva ajustada, exemplo abaixo, fazer no ggplot), resultado do goodness of fit (gof_ds()), cada modelo vai ter que ter um nome diferente numa tabela(?)

plot(cutia_tap_arap_hn, breaks = seq(0, 20, 2.5))

plot(cutia_tap_arap_hn_herm, breaks = seq(0, 20, 2.5))

plot(cutia_tap_arap_hn_cos, breaks = seq(0, 20, 2.5))

plot(cutia_tap_arap_hr, breaks = seq(0, 20, 2.5))

plot(cutia_tap_arap_hr_poly, breaks = seq(0, 20, 2.5))

plot(cutia_tap_arap_hr_cos, breaks = seq(0, 20, 2.5))

Checagem e seleção de modelos

Podemos usar a função summary para obter informações importantes sobre o modelo.


lista_modelos <- list(
  cutia_tap_arap_hn,
  cutia_tap_arap_hn_herm,
  cutia_tap_arap_hn_cos,
  cutia_tap_arap_hr,
  cutia_tap_arap_hr_poly,
  cutia_tap_arap_hr_cos
)

purrr::map(lista_modelos, \(x) summary(x))
[[1]]

Summary for distance analysis 
Number of observations :  1277 
Distance range         :  0  -  20 

Model : Half-normal key function 
AIC   : 7212.428 

Detection function parameters
Scale coefficient(s):  
NA

Summary statistics:

Density:

[[2]]

Summary for distance analysis 
Number of observations :  1277 
Distance range         :  0  -  20 

Model : Half-normal key function 
AIC   : 7212.428 

Detection function parameters
Scale coefficient(s):  
NA

Summary statistics:

Density:

[[3]]

Summary for distance analysis 
Number of observations :  1277 
Distance range         :  0  -  20 

Model : Half-normal key function with cosine adjustment terms of order 2,3,4,5 

Strict monotonicity constraints were enforced.
AIC   : 7130.51 

Detection function parameters
Scale coefficient(s):  

Adjustment term coefficient(s):  
NA

Summary statistics:

Density:

[[4]]

Summary for distance analysis 
Number of observations :  1277 
Distance range         :  0  -  20 

Model : Hazard-rate key function 
AIC   : 6888.167 

Detection function parameters
Scale coefficient(s):  

Shape coefficient(s):  
NA

Summary statistics:

Density:

[[5]]

Summary for distance analysis 
Number of observations :  1277 
Distance range         :  0  -  20 

Model : Hazard-rate key function 
AIC   : 6888.167 

Detection function parameters
Scale coefficient(s):  

Shape coefficient(s):  
NA

Summary statistics:

Density:

[[6]]

Summary for distance analysis 
Number of observations :  1277 
Distance range         :  0  -  20 

Model : Hazard-rate key function 
AIC   : 6888.167 

Detection function parameters
Scale coefficient(s):  

Shape coefficient(s):  
NA

Summary statistics:

Density:
NA
summarize_ds_models(
  cutia_tap_arap_hn,
  cutia_tap_arap_hn_herm,
  cutia_tap_arap_hn_cos,
  cutia_tap_arap_hr,
  cutia_tap_arap_hr_poly,
  cutia_tap_arap_hr_cos
)

O resultado inclui detalhes sobre o dado e a especificação do modelo, assim como dos coeficientes (\(\beta_{j}\)) e sua inceteza, a média do valor de detectabilidade e sua incerteza e uma estimativa da abundância na área coberta pela amostragem (sem levar em consideração o tamanho dos agrupamentos, ou bandos).

Bondade de ajuste

Para visualizar quão bem a função de detecção se ajusta aos dados quanto temos as distâncias exatas podemos usar um plot de quantis empíricos x teóricos (Q-Q plot). Ele compara a função de distribuição cumulativa (CDF) dos valores ajustados da função detecção a distribuição empírica dos dados (EDF).

Também podemos usar o teste de Cramér-von Mises para testar se os pontos da EDF e da CDF tem origem na mesma distribuição. O teste usa a soma de todas as distâncias entre um ponto e a linha y = x para formar a estatística a ser testada. Um resultado significativo fornece evidência contra a hiipótese nula, sugerindo que o modelo não se ajusta bem aos dados.

# ajustando um modelo Half-normal
cutia_hn <- ds(data = cutia_tap_arap_15,
                 truncation = 20,
                 transect = "line",
                 key = "hn", 
                 adjustment = NULL)

# conduzindo o teste dfe bondadede ajuste de Cramer-von Mises
gof_ds(cutia_hn)

gof_ds(cutia_hr_time)

O resutlado do teste aponta que o modelo Half-normal deve ser descartado.

Testes de bondade de ajuste de chi-quadrado são gerados usando a função gof_ds quando as distâncias forneceidas estão categorizadas.

Seleção de Modelos

Uma vez que temos um conjunto de modelos plausíveis, podemos utilizar o cirtériode informaçãode Akaike (AIC) para selecionar entre os modelos o que melhor se ajusta aos dados utilizando a função summarize_ds_models.

# ajustando a função de detecção para uma distancia de truncamento de 20 metros
# Key function - Half-normal 
cutia_tap_arap_hn_herm <- cutia_tap_arap |> 
  ds(
    truncation = 10,
    key = "hn",
    adjustment = "herm"
  )
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 4676.418
Fitting half-normal key function with Hermite(4) adjustments
AIC= 4677.111

Half-normal key function selected.

O melhor modelo é o Hazard-rate com tempo de senso e tamanho do grupo como covariáveis.

Estimando a abundância e a variância

Estimando abundância e variância no R

Para obter a abundância na região de estudo, primeiro calculamos a abundância na área amostrada para obter \(N_c\) e em seguida escalonamos esse valor para toda a área de estudo multiplicando \(N_c\) pela razão entre a área amostrada e a área da região. Para estimar a abundância na área amostrada, utilizamos as estimativas de probabilidade de detecção no estimador de Horvitz-Thompson.

Quando fornecemos os dados no formato correto (“flatfile”) ds irá automaticamente calcular as estimativas de abundância baseado nas informações de amostragem presenta nos dados.

# ajustando a função de detecção para uma distancia de truncamento de 20 metros
# Key function - Half-normal 
cutia_tap_arap_hn_cos <- cutia_tap_arap |> 
  ds(
    truncation = 10,
    key = "hn"
    )
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 4676.418
Fitting half-normal key function with cosine(2) adjustments
AIC= 4616.112
Fitting half-normal key function with cosine(2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4606.713
Fitting half-normal key function with cosine(2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4538.956
Fitting half-normal key function with cosine(2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 6262.112

Half-normal key function with cosine(2,3,4) adjustments selected.
Warning: Detection function is not strictly monotonic!
  1. Summary statistics: fornece as áreas, aŕea de amostragem, esforço, número de observações, número de transectos, taxa de encontro, seus erros padrões e coeficientes de variação para cada estrato;

  2. Abundance: fornece estimativas, erros padrões, coeficientesde variação, intervalos de confiança inferior e superior, graus de liberdade para a estimativa de abundância de cada estrato;

  3. Densidade: lista as mesmas estatísticas de Abundance, só que para densidade.

Funções Exploratórias Adicionais

contar_n_repeticoes_trilha() - conta o número de vezes que cada trilha foi visitada

Adicionando covariavel

Ajuste Hermite pollynomial usa od código "herm" e polinomial simples "poly".

Podemos incluir covariáveis utilizando o argumento formula = ~ .... Abaixo, está especificado um modelo “Hazard-rate” para os dados de cutia q ue inclui o tempo de senso como covariável e uma distância limite de 20m.

cutia_hr_time <- cutia_tap_arap_15 |> 
  ds(truncation = 20,
     key = "hr",
     formula = ~ cense_time)

Adicionando uma segunda covariável: tamanho do grupo.

cutia_hr_time_size <- ds(data = cutia_tap_arap_15,
                     truncation = 20,
                     transect = "line",
                     key = "hr",
                     formula = ~ cense_time + size)
plot(cutia_hr_time)
plot(cutia_hr_time_size)

Cutias da ESEC Terra do Meio para diferentes distâncias de truncamento

# desenha o grafico com a distribuicao de distancias perpendiculares
cutia_esec_terra_meio |> 
  filter(distance >= 1,
         distance < 15) |> 
  plotar_distribuicao_distancia_interativo(largura_caixa = 1)
Warning: Continuous y aesthetic
ℹ did you forget `aes(group = ...)`?

Half-Normal sem termos de ajuste e com termos de ajuste Cosseno e Polinomial de Hermite

Ajustando um modelo ao dados das cutias Dasyprocta croconota, configurando uma distância limite de 20m e usando Half-normal como key function usando o argumento key, sem termo de ajuste.

cutia_esec_terra_meio_filtrado
cutia_esec_terra_meio_filtrado <- cutia_esec_terra_meio |> 
  filter(distance >= 1,
         distance < 15)
# ajustando a função de detecção para uma distancia de truncamento de 20, 15, 10 e 5 metros
# dsitancias de truncamento
dist_truncamento <- list(
  #`20 metros` = 20, 
  `15 metros` = 15, 
  `12 metros` = 12,
  `10 metros` = 10
)

# Key function - Half-normal 
cutia_esec_terra_meio_hn <- purrr::map(
  dist_truncamento,
  \(.x) ajuste_modelos_distance_hn(
    cutia_esec_terra_meio_filtrado, 
    truncamento = .x
  )
  )
Fitting half-normal key function
AIC= 937.833
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 937.833
Fitting half-normal key function with cosine(2) adjustments
AIC= 936.52
Fitting half-normal key function with cosine(2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 933.054
Fitting half-normal key function with cosine(2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 932.305
Fitting half-normal key function with cosine(2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 947.384

Half-normal key function with cosine(2,3,4) adjustments selected.
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 937.833
Fitting half-normal key function with Hermite(4) adjustments
AIC= 938.647

Half-normal key function selected.
Fitting half-normal key function
AIC= 807.11
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 807.11
Fitting half-normal key function with cosine(2) adjustments
Warning: First partial hessian is singular; using second-partial hessian
Warning: Detection function is not weakly monotonic!Warning: Detection function is not strictly monotonic!Warning: Detection function is greater than 1 at some distancesWarning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Half-normal key function selected.
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 807.11
Fitting half-normal key function with Hermite(4) adjustments
Warning: First partial hessian is singular; using second-partial hessian
AIC= 809.11

Half-normal key function selected.
Fitting half-normal key function
AIC= 632.908
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 632.908
Fitting half-normal key function with cosine(2) adjustments
Warning: First partial hessian is singular; using second-partial hessian
Warning: Detection function is not weakly monotonic!Warning: Detection function is not strictly monotonic!Warning: Detection function is greater than 1 at some distancesWarning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Half-normal key function selected.
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 632.908
Fitting half-normal key function with Hermite(4) adjustments
AIC= 634.908

Half-normal key function selected.
cutia_esec_terra_meio_hn

Hazard-Rate sem termos de ajuste e com termos de ajuste Cosseno e Polinomial de Hermite

Ajustando um modelo ao dados da cutia Dasyprocta croconota, configurando uma distância limite de 20m e usando Hazard rate como key function usando o argumento key.

# ajustando a função de detecção para uma distancia de truncamento de 20, 15, 10 e 5 metros
# Key function - Hazard-rate
cutia_esec_terra_meio_hr <- purrr::map(
  dist_truncamento,
  \(.x) ajuste_modelos_distance_hr(
    cutia_esec_terra_meio_filtrado, 
    truncamento = .x
  )
  )
Fitting hazard-rate key function
AIC= 925.724
Starting AIC adjustment term selection.
Fitting hazard-rate key function
AIC= 925.724
Fitting hazard-rate key function with cosine(2) adjustments
AIC= 927.806

Hazard-rate key function selected.
Starting AIC adjustment term selection.
Fitting hazard-rate key function
AIC= 925.724
Fitting hazard-rate key function with simple polynomial(4) adjustments
AIC= 927.806

Hazard-rate key function selected.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 808.565
Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 808.565
Fitting hazard-rate key function with cosine(2) adjustments
Warning: First partial hessian is singular; using second-partial hessian
Warning: Detection function is not weakly monotonic!Warning: Detection function is not strictly monotonic!Warning: Detection function is greater than 1 at some distancesWarning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 808.565
Fitting hazard-rate key function with simple polynomial(4) adjustments
Warning: First partial hessian is singular; using second-partial hessian
AIC= 811.11

Hazard-rate key function selected.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 634.448
Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 634.448
Fitting hazard-rate key function with cosine(2) adjustments
AIC= 636.958

Hazard-rate key function selected.
Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: First partial hessian is singular; using second-partial hessian
AIC= 634.448
Fitting hazard-rate key function with simple polynomial(4) adjustments
Warning: First partial hessian is singular; using second-partial hessian
AIC= 636.908

Hazard-rate key function selected.

Uniform sem termos de ajuste e com termos de ajuste Cosseno e Polinomial de Hermite

Ajustando um modelo ao dados das cutias Dasyprocta croconota, configurando uma distância limite de 20m e usando Uniform como key function usando o argumento key, sem termo de ajuste.

# ajustando a função de detecção para uma distancia de truncamento de 20, 15, 10 e 5 metros
# Key function - Uniform
cutia_esec_terra_meio_unif <- purrr::map(
  dist_truncamento,
  \(.x) ajuste_modelos_distance_unif(
    cutia_tap_arap, 
    truncamento = .x
  )
  )
Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 6477.656
Fitting uniform key function with cosine(1) adjustments
AIC= 6288.798
Fitting uniform key function with cosine(1,2) adjustments
AIC= 6280.568
Fitting uniform key function with cosine(1,2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 6248.532
Fitting uniform key function with cosine(1,2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 6238.947
Fitting uniform key function with cosine(1,2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 6210.006
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 6477.656
Fitting uniform key function with simple polynomial(2) adjustments
AIC= 6345.058
Fitting uniform key function with simple polynomial(2,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 6290.986
Fitting uniform key function with simple polynomial(2,4,6) adjustments
Warning: Detection function is not strictly monotonic!AIC= 6288.551
Fitting uniform key function with simple polynomial(2,4,6,8) adjustments
Warning: Detection function is not strictly monotonic!AIC= 6288.125
Fitting uniform key function with simple polynomial(2,4,6,8,10) adjustments
Warning: Detection function is not strictly monotonic!AIC= 6284.527
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 5432.006
Fitting uniform key function with cosine(1) adjustments
AIC= 5340.635
Fitting uniform key function with cosine(1,2) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5319.03
Fitting uniform key function with cosine(1,2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5282.176
Fitting uniform key function with cosine(1,2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5271.725
Fitting uniform key function with cosine(1,2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5213.714
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 5432.006
Fitting uniform key function with simple polynomial(2) adjustments
AIC= 5366.091
Fitting uniform key function with simple polynomial(2,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5346.537
Fitting uniform key function with simple polynomial(2,4,6) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5338.476
Fitting uniform key function with simple polynomial(2,4,6,8) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5332.686
Fitting uniform key function with simple polynomial(2,4,6,8,10) adjustments
Warning: Detection function is not strictly monotonic!AIC= 5326.193
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 4688.063
Fitting uniform key function with cosine(1) adjustments
AIC= 4647.342
Fitting uniform key function with cosine(1,2) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4617.841
Fitting uniform key function with cosine(1,2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4579.748
Fitting uniform key function with cosine(1,2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4551.3
Fitting uniform key function with cosine(1,2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4523.924
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 4688.063
Fitting uniform key function with simple polynomial(2) adjustments
AIC= 4680.313
Fitting uniform key function with simple polynomial(2,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4651.715
Fitting uniform key function with simple polynomial(2,4,6) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4637.792
Fitting uniform key function with simple polynomial(2,4,6,8) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4631.554
Fitting uniform key function with simple polynomial(2,4,6,8,10) adjustments
Warning: Detection function is not strictly monotonic!AIC= 4622.947
Warning: Detection function is not strictly monotonic!
Seleção de modelos
summarize_ds_models(
  cutia_esec_terra_meio_hn$`20 metros`$`Sem termo`,
cutia_esec_terra_meio_hn$`20 metros`$Cosseno,
  cutia_esec_terra_meio_hn$`20 metros`$`Hermite polinomial`,
cutia_esec_terra_meio_hr$`20 metros`$`Sem termo`,
cutia_esec_terra_meio_hr$`20 metros`$Cosseno,
cutia_esec_terra_meio_hr$`20 metros`$`Polinomial simples`,
cutia_esec_terra_meio_unif$`20 metros`$Cosseno,
cutia_esec_terra_meio_unif$`20 metros`$`Polinomial simples`
)
Warning: argumento não é numérico nem lógico: retornando NAWarning: argumento não é numérico nem lógico: retornando NAError in !binned : argumento de tipo inválido
summarize_ds_models(
  cutia_esec_terra_meio_hn$`15 metros`$`Sem termo`,
cutia_esec_terra_meio_hn$`15 metros`$Cosseno,
  cutia_esec_terra_meio_hn$`15 metros`$`Hermite polinomial`,
cutia_esec_terra_meio_hr$`15 metros`$`Sem termo`,
cutia_esec_terra_meio_hr$`15 metros`$Cosseno,
cutia_esec_terra_meio_hr$`15 metros`$`Polinomial simples`,
cutia_esec_terra_meio_unif$`15 metros`$Cosseno,
cutia_esec_terra_meio_unif$`15 metros`$`Polinomial simples`
)
summarize_ds_models(
  cutia_esec_terra_meio_hn$`10 metros`$`Sem termo`,
cutia_esec_terra_meio_hn$`10 metros`$Cosseno,
  cutia_esec_terra_meio_hn$`10 metros`$`Hermite polinomial`,
cutia_esec_terra_meio_hr$`10 metros`$`Sem termo`,
cutia_esec_terra_meio_hr$`10 metros`$Cosseno,
cutia_esec_terra_meio_hr$`10 metros`$`Polinomial simples`,
cutia_esec_terra_meio_unif$`10 metros`$Cosseno,
cutia_esec_terra_meio_unif$`10 metros`$`Polinomial simples`
)
summarize_ds_models(
  cutia_esec_terra_meio_hn$`12 metros`$`Sem termo`,
cutia_esec_terra_meio_hn$`12 metros`$Cosseno,
  cutia_esec_terra_meio_hn$`12 metros`$`Hermite polinomial`,
cutia_esec_terra_meio_hr$`12 metros`$`Sem termo`,
cutia_esec_terra_meio_hr$`12 metros`$Cosseno,
cutia_esec_terra_meio_hr$`12 metros`$`Polinomial simples`,
cutia_esec_terra_meio_unif$`12 metros`$Cosseno,
cutia_esec_terra_meio_unif$`12 metros`$`Polinomial simples`
)

Cutias da Parna da Serra do Pardo para diferentes distâncias de truncamento

# desenha o grafico com a distribuicao de distancias perpendiculares
cutia_parna_serra_pardo |> 
  filter(distance < 15,
         distance > 0) |> 
  plotar_distribuicao_distancia_interativo()
Warning: Continuous y aesthetic
ℹ did you forget `aes(group = ...)`?

Half-Normal sem termos de ajuste e com termos de ajuste Cosseno e Polinomial de Hermite

Ajustando um modelo ao dados das cutias Dasyprocta croconota, configurando uma distância limite de 20m e usando Half-normal como key function usando o argumento key, sem termo de ajuste.

# ajustando a função de detecção para uma distancia de truncamento de 20, 15, 10 e 5 metros
# dsitancias de truncamento
dist_truncamento <- list(
  `20 metros` = 20, 
  `15 metros` = 15, 
  `10 metros` = 10,
  `5 metros` = 5
)

# Key function - Half-normal 
cutia_parna_serra_pardo_hn <- purrr::map(
  dist_truncamento,
  \(.x) ajuste_modelos_distance_hn(
    cutia_parna_serra_pardo, 
    truncamento = .x
  )
  )
Fitting half-normal key function
AIC= 1400.725
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 1400.725
Fitting half-normal key function with cosine(2) adjustments
AIC= 1402.141

Half-normal key function selected.
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 1400.725
Fitting half-normal key function with Hermite(4) adjustments
AIC= 1402.044

Half-normal key function selected.
Fitting half-normal key function
AIC= 1315.127
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 1315.127
Fitting half-normal key function with cosine(2) adjustments
AIC= 1315.224

Half-normal key function selected.
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 1315.127
Fitting half-normal key function with Hermite(4) adjustments
AIC= 1317.126

Half-normal key function selected.
Fitting half-normal key function
AIC= 943.522
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 943.522
Fitting half-normal key function with cosine(2) adjustments
AIC= 934.647
Fitting half-normal key function with cosine(2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 934.508
Fitting half-normal key function with cosine(2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 947.489

Half-normal key function with cosine(2,3) adjustments selected.
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 943.522
Fitting half-normal key function with Hermite(4) adjustments
AIC= 945.333

Half-normal key function selected.
Fitting half-normal key function
AIC= 397.926
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 397.926
Fitting half-normal key function with cosine(2) adjustments
Warning: Detection function is not strictly monotonic!AIC= 370.676
Fitting half-normal key function with cosine(2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 366.578
Fitting half-normal key function with cosine(2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 837.783

Half-normal key function with cosine(2,3) adjustments selected.
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 397.926
Fitting half-normal key function with Hermite(4) adjustments
AIC= 399.683

Half-normal key function selected.
cutia_parna_serra_pardo_hn
$`20 metros`
$`20 metros`$`Sem termo`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 519.0546 

$`20 metros`$Cosseno

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 519.0546 

$`20 metros`$`Hermite polinomial`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 519.0546 


$`15 metros`
$`15 metros`$`Sem termo`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 368.4514 

$`15 metros`$Cosseno

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 368.4514 

$`15 metros`$`Hermite polinomial`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 368.4514 


$`10 metros`
$`10 metros`$`Sem termo`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 231.447 

$`10 metros`$Cosseno

Distance sampling analysis object

Detection function:
 Half-normal key function with cosine adjustment terms of order 2,3 

Estimated abundance in covered region: 319.3262 

$`10 metros`$`Hermite polinomial`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 231.447 


$`5 metros`
$`5 metros`$`Sem termo`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 147.5382 

$`5 metros`$Cosseno

Distance sampling analysis object

Detection function:
 Half-normal key function with cosine adjustment terms of order 2,3 

Estimated abundance in covered region: 264.7876 

$`5 metros`$`Hermite polinomial`

Distance sampling analysis object

Detection function:
 Half-normal key function 

Estimated abundance in covered region: 147.5382 

Hazard-Rate sem termos de ajuste e com termos de ajuste Cosseno e Polinomial de Hermite

Ajustando um modelo ao dados da cutia Dasyprocta croconota, configurando uma distância limite de 20m e usando Hazard rate como key function usando o argumento key.

# ajustando a função de detecção para uma distancia de truncamento de 20, 15, 10 e 5 metros
# Key function - Hazard-rate
cutia_parna_serra_pardo_hr <- purrr::map(
  dist_truncamento,
  \(.x) ajuste_modelos_distance_hr(
    cutia_parna_serra_pardo, 
    truncamento = .x
  )
  )
Fitting hazard-rate key function
AIC= 1402.11
Starting AIC adjustment term selection.
Fitting hazard-rate key function
AIC= 1402.11
Fitting hazard-rate key function with cosine(2) adjustments
AIC= 1396.291
Fitting hazard-rate key function with cosine(2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 1393.787
Fitting hazard-rate key function with cosine(2,3,4) adjustments
Warning: Detection function is not weakly monotonic!Warning: Detection function is not strictly monotonic!Warning: Detection function is greater than 1 at some distancesWarning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function with cosine(2,3) adjustments selected.
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting hazard-rate key function
AIC= 1402.11
Fitting hazard-rate key function with simple polynomial(4) adjustments
AIC= 1408.986

Hazard-rate key function selected.
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 1252.293
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 1252.293
Fitting hazard-rate key function with cosine(2) adjustments
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 1252.293
Fitting hazard-rate key function with simple polynomial(4) adjustments
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 821.762
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 821.762
Fitting hazard-rate key function with cosine(2) adjustments
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 821.762
Fitting hazard-rate key function with simple polynomial(4) adjustments
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Fitting hazard-rate key function
AIC= 76.172
Starting AIC adjustment term selection.
Fitting hazard-rate key function
AIC= 76.172
Fitting hazard-rate key function with cosine(2) adjustments
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.
Starting AIC adjustment term selection.
Fitting hazard-rate key function
AIC= 76.172
Fitting hazard-rate key function with simple polynomial(4) adjustments
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Warning: Model fitting did not converge. Try different initial values or different model
  Model failed to converge.

Hazard-rate key function selected.

Uniform sem termos de ajuste e com termos de ajuste Cosseno e Polinomial de Hermite

Ajustando um modelo ao dados das cutias Dasyprocta croconota, configurando uma distância limite de 20m e usando Uniform como key function usando o argumento key, sem termo de ajuste.

# ajustando a função de detecção para uma distancia de truncamento de 20, 15, 10 e 5 metros
# Key function - Uniform
cutia_parna_serra_pardo_unif <- purrr::map(
  dist_truncamento,
  \(.x) ajuste_modelos_distance_unif(
    cutia_parna_serra_pardo, 
    truncamento = .x
  )
)
Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 1527.823
Fitting uniform key function with cosine(1) adjustments
AIC= 1397.715
Fitting uniform key function with cosine(1,2) adjustments
AIC= 1399.656

Uniform key function with cosine(1) adjustments selected.
Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 1527.823
Fitting uniform key function with simple polynomial(2) adjustments
AIC= 1430.868
Fitting uniform key function with simple polynomial(2,4) adjustments
AIC= 1400.747
Fitting uniform key function with simple polynomial(2,4,6) adjustments
Warning: Detection function is not strictly monotonic!AIC= 1399.677
Fitting uniform key function with simple polynomial(2,4,6,8) adjustments
Warning: Detection function is not strictly monotonic!AIC= 1401.389

Uniform key function with simple polynomial(2,4,6) adjustments selected.
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 1348.609
Fitting uniform key function with cosine(1) adjustments
AIC= 1316.18
Fitting uniform key function with cosine(1,2) adjustments
AIC= 1318.11

Uniform key function with cosine(1) adjustments selected.
Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 1348.609
Fitting uniform key function with simple polynomial(2) adjustments
AIC= 1316.568
Fitting uniform key function with simple polynomial(2,4) adjustments
AIC= 1317.168

Uniform key function with simple polynomial(2) adjustments selected.
Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 944.06
Fitting uniform key function with cosine(1) adjustments
AIC= 939.555
Fitting uniform key function with cosine(1,2) adjustments
Warning: Detection function is not strictly monotonic!AIC= 936.452
Fitting uniform key function with cosine(1,2,3) adjustments
Warning: Detection function is not strictly monotonic!AIC= 931.427
Fitting uniform key function with cosine(1,2,3,4) adjustments
Warning: Detection function is not strictly monotonic!AIC= 928.341
Fitting uniform key function with cosine(1,2,3,4,5) adjustments
Warning: Detection function is not strictly monotonic!AIC= 923.816
Warning: Detection function is not strictly monotonic!Starting AIC adjustment term selection.
Fitting uniform key function
AIC= 944.06
Fitting uniform key function with simple polynomial(2) adjustments
AIC= 944.093

Uniform key function selected.
Error in `purrr::map()`:
ℹ In index: 3.
ℹ With name: 10 metros.
Caused by error in `purrr::map()`:
ℹ In index: 2.
ℹ With name: Polinomial simples.
Caused by error in `t.default()`:
! argumento não é uma matriz
Backtrace:
  1. purrr::map(...)
  2. purrr:::map_("list", .x, .f, ..., .progress = .progress)
  6. global .f(.x[[i]], ...)
  7. global ajuste_modelos_distance_unif(cutia_parna_serra_pardo, truncamento = .x)
  8. purrr::map(...)
  9. purrr:::map_("list", .x, .f, ..., .progress = .progress)
 13. .f(.x[[i]], ...)
 14. Distance::ds(...)
 15. mrds::dht(...)
 18. base::t.default(clusters$vc$detection$partial)
Seleção de modelos
summarize_ds_models(
  cutia_parna_serra_pardo_hn$`20 metros`$`Sem termo`,
cutia_parna_serra_pardo_hn$`20 metros`$Cosseno,
  cutia_parna_serra_pardo_hn$`20 metros`$`Hermite polinomial`,
cutia_parna_serra_pardo_hr$`20 metros`$`Sem termo`,
cutia_parna_serra_pardo_hr$`20 metros`$Cosseno,
cutia_parna_serra_pardo_hr$`20 metros`$`Polinomial simples`
)
summarize_ds_models(
  cutia_parna_serra_pardo_hn$`15 metros`$`Sem termo`,
cutia_parna_serra_pardo_hn$`15 metros`$Cosseno,
  cutia_parna_serra_pardo_hn$`15 metros`$`Hermite polinomial`,
cutia_parna_serra_pardo_hr$`15 metros`$`Sem termo`,
cutia_parna_serra_pardo_hr$`15 metros`$Cosseno,
cutia_parna_serra_pardo_hr$`15 metros`$`Polinomial simples`
)
summarize_ds_models(
  cutia_parna_serra_pardo_hn$`10 metros`$`Sem termo`,
cutia_parna_serra_pardo_hn$`10 metros`$Cosseno,
  cutia_parna_serra_pardo_hn$`10 metros`$`Hermite polinomial`,
cutia_parna_serra_pardo_hr$`10 metros`$`Sem termo`,
cutia_parna_serra_pardo_hr$`10 metros`$Cosseno,
cutia_parna_serra_pardo_hr$`10 metros`$`Polinomial simples`
)
summarize_ds_models(
  cutia_parna_serra_pardo_hn$`5 metros`$`Sem termo`,
cutia_parna_serra_pardo_hn$`5 metros`$Cosseno,
  cutia_parna_serra_pardo_hn$`5 metros`$`Hermite polinomial`,
cutia_parna_serra_pardo_hr$`5 metros`$`Sem termo`,
cutia_parna_serra_pardo_hr$`5 metros`$Cosseno,
cutia_parna_serra_pardo_hr$`5 metros`$`Polinomial simples`
)
Tentativa de fazer a seleçã ode modelos usando purrr - tentar aninhar mais um map
purrr::map_df(
  list(
    cutia_esec_terra_meio_hn$`20 metros`,
    cutia_esec_terra_meio_hr$`20 metros`
  ),
  \(.x) purrr::map_df(.x, \(.y) summarize_ds_models(.y))
)

purrr::map_df(
  cutia_esec_terra_meio_hn$`15 metros`,
  \(.x) summarize_ds_models(.x)
)

purrr::map_df(
  cutia_esec_terra_meio_hn$`10 metros`,
  \(.x) summarize_ds_models(.x)
)

purrr::map_df(
  cutia_esec_terra_meio_hn$`5 metros`,
  \(.x) summarize_ds_models(.x)
)

Sugestões chat GPT

Pergunta 1 - Falta de monotonicidade na função de detecção

Estou ajustando modelos de amostragem por distância para obter estimativa de densidade de objetos utilizando o pacote Distance no ambiente de programação R. Alguns dos modelos aos dados estão apresentando problemas de falta de monotonicidade na função de detecção. Tem alguma sugestão de como posso resolver o problema de falta de monotonicidade na função de detecção?

Resposta: A falta de monotonicidade na função de detecção em modelos de amostragem por distância pode ser um desafio, mas existem algumas abordagens que você pode tentar para resolver esse problema. Aqui estão algumas sugestões:

  1. Verifique os dados: Primeiro, verifique se os seus dados estão corretos e se não há erros na sua preparação ou processamento. Erros nos dados podem levar a resultados não esperados e à falta de monotonicidade na função de detecção.

  2. Ajuste de parâmetros: Experimente ajustar os parâmetros do modelo de amostragem por distância. Por exemplo, você pode alterar o valor do raio de busca (search radius) ou do número mínimo de vizinhos necessários para detecção. Pequenas alterações nesses parâmetros podem ter um impacto significativo na monotonicidade da função de detecção.

  3. Transformações dos dados: Considere aplicar transformações nos seus dados antes de ajustar o modelo. Por exemplo, você pode tentar aplicar uma transformação logarítmica ou uma transformação Box-Cox para reduzir a escala dos dados e torná-los mais adequados para o modelo de amostragem por distância.

  4. Suavização: Se você identificar regiões com falta de monotonicidade na função de detecção, pode ser útil aplicar técnicas de suavização. Por exemplo, você pode utilizar técnicas de suavização local, como o kernel smoothing, para tornar a função de detecção mais suave e monotônica.

  5. Outros modelos ou métodos: Se os modelos de amostragem por distância continuarem a apresentar problemas de falta de monotonicidade, talvez seja necessário explorar outros modelos ou métodos de estimativa de densidade. Existem diversas abordagens disponíveis na literatura, como modelos baseados em krigagem ou métodos de estimativa de densidade kernel.

  6. Validação cruzada: Realize uma validação cruzada do seu modelo para avaliar sua capacidade de generalização. Às vezes, a falta de monotonicidade pode ser causada por overfitting nos dados de treinamento. A validação cruzada pode ajudar a identificar esse problema e orientar ajustes adicionais no modelo.

Lembre-se de que a falta de monotonicidade na função de detecção pode indicar uma inadequação do modelo em relação aos seus dados ou características específicas do problema em questão. Portanto, pode ser necessário explorar diferentes abordagens e técnicas para obter resultados satisfatórios.

Pergunta 2: Falta de convergência

A falta de convergência em modelos de amostragem por distância pode ser um desafio, mas existem algumas sugestões que você pode seguir para tentar resolver esse problema. Aqui estão algumas opções:

  1. Verifique os dados: Verifique se os seus dados estão corretos e se não há erros na preparação ou processamento dos mesmos. Erros nos dados podem levar a problemas de convergência. Verifique também se não há valores extremos ou dados ausentes que possam estar afetando o ajuste do modelo.

  2. Reduza a complexidade do modelo: Se o seu modelo atual é muito complexo, pode ser difícil obter a convergência. Considere reduzir a complexidade do modelo, diminuindo o número de parâmetros a serem estimados ou simplificando a estrutura do modelo.

  3. Inicialização adequada: Tente fornecer uma boa inicialização para os parâmetros do modelo. Isso pode ajudar a evitar problemas de convergência. Se possível, utilize valores iniciais próximos dos valores verdadeiros dos parâmetros ou utilize resultados de modelos anteriores como ponto de partida.

  4. Ajuste dos parâmetros do algoritmo de otimização: Muitas vezes, o problema de falta de convergência está relacionado aos parâmetros do algoritmo de otimização utilizado para ajustar o modelo. Experimente ajustar esses parâmetros, como o tamanho do passo (step size), a tolerância de convergência (convergence tolerance) ou o número máximo de iterações permitidas. Tente diferentes combinações de valores para esses parâmetros e observe se isso ajuda a alcançar a convergência.

  5. Normalização dos dados: Considere normalizar os seus dados antes de ajustar o modelo. Isso pode ajudar a evitar problemas numéricos ou de escala que possam afetar a convergência. Normalizar os dados para uma escala com média zero e desvio padrão igual a um é uma abordagem comum.

  6. Explorar outros algoritmos ou métodos: Se o modelo de amostragem por distância continuar apresentando problemas de convergência, você pode considerar explorar outros algoritmos ou métodos para estimativa de densidade. Existem diferentes abordagens disponíveis na literatura, como métodos baseados em Máxima Verossimilhança (Maximum Likelihood) ou algoritmos de Monte Carlo.

  7. Verifique a documentação e recursos do pacote: Verifique a documentação do pacote Distance e os recursos disponíveis para encontrar informações específicas sobre os problemas de convergência e possíveis soluções. Fóruns de discussão ou grupos de usuários relacionados ao pacote também podem ser úteis para obter suporte e orientação.

Lembre-se de que a falta de convergência pode ter várias causas e não há uma solução única para todos os casos. É importante iterar e experimentar diferentes abordagens até encontrar uma solução adequada para o seu problema específico.

Pergunta 3: Pico próximo da distância zero

Picos próximos a distância zero podem ser um desafio ao ajustar modelos de amostragem por distância. Esses picos podem indicar a presença de pontos muito próximos uns dos outros, o que pode impactar negativamente a estimativa de densidade. Aqui estão algumas sugestões para lidar com esse problema:

  1. Verifique a qualidade dos dados: Verifique se os seus dados estão corretos e se não há erros na preparação ou processamento dos mesmos. Erros nos dados podem levar a picos próximos a distância zero. Verifique também se não há pontos duplicados ou dados ausentes que possam estar causando esses picos.

  2. Limpeza dos dados: Considere a possibilidade de remover ou ajustar pontos próximos demais uns dos outros. Você pode definir um limiar de distância mínima abaixo do qual os pontos serão considerados duplicados ou fundidos em um único ponto. Isso pode ajudar a evitar os picos próximos a distância zero.

  3. Transformação dos dados: Considere aplicar uma transformação nos dados antes de ajustar o modelo. Por exemplo, você pode tentar aplicar uma transformação logarítmica ou uma transformação Box-Cox para reduzir a escala dos dados e suavizar os picos próximos a distância zero.

  4. Utilize um raio de busca maior: Experimente aumentar o raio de busca (search radius) utilizado no modelo de amostragem por distância. Isso pode ajudar a capturar informações sobre a densidade em uma região mais ampla ao redor de cada ponto e reduzir a influência dos picos próximos a distância zero.

  5. Considere outros modelos ou métodos: Se os picos próximos a distância zero continuarem a ser um problema, você pode explorar outros modelos ou métodos de estimativa de densidade que sejam mais robustos a esse tipo de situação. Por exemplo, modelos baseados em kernel podem ser uma alternativa viável, pois permitem uma suavização mais flexível e podem lidar melhor com a presença de picos próximos.

  6. Experimente diferentes configurações: Faça experimentos com diferentes configurações e parâmetros do modelo de amostragem por distância. Isso inclui a escolha do tipo de função de detecção e a definição de parâmetros relacionados à detecção e ao suavização dos picos próximos a distância zero.

Lembre-se de que a solução ideal dependerá das características específicas dos seus dados e do problema em questão. É importante iterar, experimentar diferentes abordagens e avaliar os resultados para encontrar a melhor solução para o seu caso.

Pergunta 4: Função de detecção maior que 1 em algumas distâncias

Se a função de detecção está apresentando valores maiores que um em algumas distâncias, isso pode indicar um problema no ajuste dos modelos de amostragem por distância. Aqui estão algumas sugestões para resolver esse problema:

  1. Verifique os dados: Verifique se os seus dados estão corretos e se não há erros na preparação ou processamento dos mesmos. Erros nos dados podem levar a resultados inesperados na função de detecção. Verifique também se não há pontos duplicados ou dados ausentes que possam afetar o ajuste do modelo.

  2. Verifique a função de detecção: Revise a função de detecção utilizada no modelo. Verifique se a função está corretamente especificada e se está sendo aplicada corretamente aos dados. Certifique-se de que não há erros de programação ou configuração que estejam causando valores maiores que um na função de detecção.

  3. Ajuste de parâmetros: Experimente ajustar os parâmetros do modelo de amostragem por distância. Por exemplo, você pode alterar o valor do raio de busca (search radius) ou o número mínimo de vizinhos necessários para detecção. Pequenas alterações nesses parâmetros podem afetar a função de detecção e evitar que ela apresente valores maiores que um.

  4. Normalização dos dados: Considere normalizar os seus dados antes de ajustar o modelo. A normalização dos dados para uma escala específica, como a escala [0, 1], pode ajudar a evitar valores maiores que um na função de detecção. Isso pode ser especialmente útil se os seus dados possuírem diferentes ordens de grandeza.

  5. Explorar outras funções de detecção: Se a função de detecção atual estiver apresentando problemas, você pode considerar utilizar outras funções de detecção disponíveis no pacote Distance ou em outros pacotes. Experimente diferentes funções para encontrar aquela que melhor se ajusta aos seus dados e evita valores maiores que um.

  6. Verifique a documentação e recursos do pacote: Consulte a documentação do pacote Distance e os recursos disponíveis para obter informações específicas sobre problemas relacionados à função de detecção e possíveis soluções. Fóruns de discussão ou grupos de usuários relacionados ao pacote também podem ser úteis para obter suporte e orientação.

Lembre-se de que é importante investigar a causa raiz do problema e iterar em diferentes abordagens até encontrar uma solução adequada para o seu caso específico.

Primeira espécie modelo

Saguinus midas no Parna Montanhas do Tumucumaque

Carregar dados

sagui_mont_tumuc <- transformar_para_distanceR_covariaveis() |> 
  filter(
    Region.Label == "Parna Montanhas do Tumucumaque",
    sp_name == "Saguinus midas"
  ) |> 
  drop_na(distance)

Distribuição das distâncias perpendiculares

sagui_mont_tumuc |> 
  plotar_distribuicao_distancia_interativo()
Warning: Continuous y aesthetic
ℹ did you forget `aes(group = ...)`?

Ajustando modelo distance com função de detecção Half-Normal e distancia de truncamento 10

sagui_mont_tumuc_hn <- sagui_mont_tumuc |> 
  ajuste_modelos_distance_hn(truncamento = 10)
Fitting half-normal key function
AIC= 353.849
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 353.849
Fitting half-normal key function with cosine(2) adjustments
AIC= 354.52

Half-normal key function selected.
Starting AIC adjustment term selection.
Fitting half-normal key function
AIC= 353.849
Fitting half-normal key function with Hermite(4) adjustments
AIC= 355.818

Half-normal key function selected.

Ajustando modelo distance com função de detecção Hazard-rate e distancia de truncamento 10

sagui_mont_tumuc_hr <- sagui_mont_tumuc |> 
  ajuste_modelos_distance_hr(truncamento = 10)
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 355.417
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 355.417
Fitting hazard-rate key function with cosine(2) adjustments
Warning: Detection function is not strictly monotonic!AIC= 356.358

Hazard-rate key function selected.
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).Starting AIC adjustment term selection.
Fitting hazard-rate key function
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 355.417
Fitting hazard-rate key function with simple polynomial(4) adjustments
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).AIC= 360.38

Hazard-rate key function selected.
Warning: Estimated hazard-rate scale parameter close to 0 (on log scale). Possible problem in data (e.g., spike near zero distance).

Plot dos modelos

sagui_mont_tumuc_hn |> 
  purrr::map(\(.x) plot(.x)) 
$`Sem termo`
NULL

$Cosseno
NULL

$`Hermite polinomial`
NULL

sagui_mont_tumuc_hr |> 
  purrr::map(\(.x) plot(.x)) 

$`Sem termo`
NULL

$Cosseno
NULL

$`Polinomial simples`
NULL

Seleção de modelos

summarize_ds_models(
  sagui_mont_tumuc_hn$`Sem termo`,
  sagui_mont_tumuc_hn$Cosseno,
  sagui_mont_tumuc_hn$`Hermite polinomial`,
  sagui_mont_tumuc_hr$`Sem termo`,
  sagui_mont_tumuc_hr$Cosseno,
  sagui_mont_tumuc_hr$`Polinomial simples`
)

Teste de bondade de ajuste

sagui_mont_tumuc_hn |> 
  purrr::map(\(.x) gof_ds(model = .x))
$`Sem termo`

Goodness of fit results for ddf object

Distance sampling Cramer-von Mises test (unweighted)
Test statistic = 0.301163 p-value = 0.134156

$Cosseno

Goodness of fit results for ddf object

Distance sampling Cramer-von Mises test (unweighted)
Test statistic = 0.301163 p-value = 0.134156

$`Hermite polinomial`

Goodness of fit results for ddf object

Distance sampling Cramer-von Mises test (unweighted)
Test statistic = 0.301163 p-value = 0.134156

sagui_mont_tumuc_hr |> 
  purrr::map(\(.x) gof_ds(model = .x))

$`Sem termo`

Goodness of fit results for ddf object

Distance sampling Cramer-von Mises test (unweighted)
Test statistic = 0.288212 p-value = 0.145969

$Cosseno

Goodness of fit results for ddf object

Distance sampling Cramer-von Mises test (unweighted)
Test statistic = 0.288212 p-value = 0.145969

$`Polinomial simples`

Goodness of fit results for ddf object

Distance sampling Cramer-von Mises test (unweighted)
Test statistic = 0.288212 p-value = 0.145969

Estimando a abundancia

(125.8 + 67.6 + 240.8)/4e+07
[1] 1.0855e-05

Tentativa de rodar o dsitance para mais de uma espécie ao de uma só vez

dados_entre_60_130_aninhado_especie <- dados_entre_60_130 |> 
  nest(sp_name)
LS0tCnRpdGxlOiAiRGlzdGFuY2Ugbm8gUiBjb20gZGFkb3MgJ21vZGVsbyciCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KClJldGlyYWRvIGRvIGFydGlnbyBNaWxsZXIgZXQgYWwuICgyMDE5KS4gRGlzdGFuY2Ugc2FtcGxpbmcgaW4gUi4gSm91cm5hbCBvZiBTdGF0aXN0aWNhbCBTb2Z3YXJlIDg5KDEpCgpgYGB7ciBzZXR1cH0KIyBpbnN0YWxhciBwYWNvdGVzIG5lY2Vzc8OhcmlvcwojaW5zdGFsbC5wYWNrYWdlcygiRGlzdGFuY2UiKQoKIyBpbnN0YWxhciBwYWNvdGVzIGFkaWNpb25haXMKI2luc3RhbGwucGFja2FnZXMoIm1yZHMiKQojaW5zdGFsbC5wYWNrYWdlcygiZHNtIikKI2luc3RhbGwucGFja2FnZXMoIm1hZHMiKQojaW5zdGFsbC5wYWNrYWdlcygiZHNpbXMiKQoKIyBjYXJyZWdhciBwYWNvdGVzIApsaWJyYXJ5KERpc3RhbmNlKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KERUKQpsaWJyYXJ5KGZsZXh0YWJsZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHRpZHlyKQoKIyBjYXJyZWdhciBhcyBmdW7Dp8O1ZXMgZGEgcGFzdGEgUgojIGNhcnJlZ2FyIGZ1bsOnw6NvIHNjcmlwdF9jYXJyZWdhcl9mdW7Dp8O1ZXNfcGFzdGFfci5SCnNvdXJjZSgKICBwYXN0ZTAoCiAgICBoZXJlOjpoZXJlKCksCiAgICAiL1IvbWluaGFzX2Z1bmNvZXMuUiIKICApCikKCiMgY2FycmVnYXIgZGFkb3MKY3V0aWFfdGFwX2FyYXAgPC0gdHJhbnNmb3JtYXJfcGFyYV9kaXN0YW5jZVJfY292YXJpYXZlaXMoKSB8PiAKICBmaWx0ZXIoCiAgICBSZWdpb24uTGFiZWwgPT0gIlJlc2V4IFRhcGFqb3MtQXJhcGl1bnMiLAogICAgc3BfbmFtZSA9PSAiRGFzeXByb2N0YSBjcm9jb25vdGEiCiAgKSB8PiAKICBkcm9wX25hKGRpc3RhbmNlKQogIAojIHJlYWRyOjp3cml0ZV9leGNlbF9jc3YoCiMgICBjdXRpYV90YXBfYXJhcCwKIyAgIHBhc3RlMCgKIyAgICAgaGVyZTo6aGVyZSgpLAojICAgICAiL2RhdGEvY3V0aWFfdGFwX2FyYXAuY3N2IgojICAgKSwKIyApCgpjdXRpYV90YXBfYXJhcCA8LSBjdXRpYV90YXBfYXJhcCB8PiAKICBzZWxlY3QoCiAgICBSZWdpb24uTGFiZWwsCiAgICBBcmVhLAogICAgU2FtcGxlLkxhYmVsLAogICAgRWZmb3J0LAogICAgZGlzdGFuY2UKICApIAoKY3V0aWFfdGFwX2FyYXAgfD4gCiAgRFQ6OmRhdGF0YWJsZShmaWx0ZXIgPSAidG9wIikKYGBgCgpgYGB7cn0KZGFkb3NfY29tcGxldG9zIHw+IAogIGdyb3VwX2J5KAogICAgdWNfbmFtZSwKICAgIGVhX25hbWUKICApIHw+IAogIGZpbHRlcihkYXlfZWZmb3J0ID09IG1heChkYXlfZWZmb3J0KSkgIHw+IAogIGRyb3BfbmEoZGlzdGFuY2UpIHw+IAogIHVuZ3JvdXAoKQpgYGAKCmBgYHtyfQpkYWRvc19jb21wbGV0b3MgfD4gCiAgZmlsdGVyKAogICAgdWNfbmFtZSA9PSAiUmVzZXggVGFwYWpvcy1BcmFwaXVucyIsCiAgICBzcF9uYW1lID09ICJEYXN5cHJvY3RhIGNyb2Nvbm90YSIKICApIHw+IAogIGRhdGF0YWJsZShmaWx0ZXIgPSBsaXN0KHBvc2l0aW9uID0gInRvcCIpKQpgYGAKCiMgRm9ybWF0YcOnw6NvIGRvIGNvbmp1bnRvIGRlIGRhZG9zCgpWYXJpw6F2ZWlzIG5lY2Vzc8OhcmlhcyBwYXJhIG8gYGRhdGEuZnJhbWVgOgoKLSBgUmVnaW9uLkxhYmVsYDogdmV0b3IgZmF0b3IgY29tIG8gZXN0cmF0byBjb250ZW5kbyBvIHRyYW5zZWN0byAocG9kZSBzZXIgdW1hIGVzdHJhdGlmaWNhw6fDo28gcHLDqS1hbW9zdHJhZ2VtIC0gVUNzIC0gb3UgcMOzcy1hbW9zdHJhZ2VtIC0gZXguIHJlZ2nDo28sIGVzdGFkbywgYmlvbWEpCgotIGBBcmVhYDogdmV0b3IgbnVtw6lyaWNvIGNvbnRlbmRvIGEgw6FyZWEgZG8gZXN0cmF0bzsKCi0gYFNhbXBsZS5MYWJlbGA6IHZldG9yIG7Dum1lcmljbyBjb250ZW5kbyBhIGlkZW50aWRhZGUgKElEKSBkbyB0cmFuc2VjdG8KCi0gYG9iamVjdGA6IG5vbWUgYWRpY2lvbmFsLCB2ZXIgc2XDp8OjbyA2OwoKLSBgZGV0ZWN0ZWRgOiBub21lIGFkaWNpb25hbCwgdmVyIHNlw6fDo28gNjsKCi0gYEVmZm9ydGA6IHZldG9yIG7Dum1lcmljbyBjb250ZW5kbyBvIGVzZm9yw6dvIGRvIHRyYW5zZWN0byAocGFyYSBsaW5oYXMgc2V1IGNvbXByaW1lbnRvLCBwYXJhIHBvbnRvcyBvIG7Dum1lcm8gZGUgdmV6ZXMgcXVlIG8gcG9udG8gZm9pIHZpc2l0YWRvKQoKLSBgc2l6ZWA6IHZldG9yIG51bcOpcmljbyBjb3BudGVuZG8gbyB0YW1hbmhvIGRvIGdydXBvIG9ic2VydmFkbzsKCi0gYGRpc3RhbmNlYDogdmV0b3IgbnVtw6lyaWNvIGRlIGRpc3TDom5jaWFzIG9ic2VydmFkYXM7CgotIGBNb250aGA6CgotIGBPQnNgOgoKLSBgU3BgOgoKIC0gYG1hc2A6CiAKIC0gYEhBU2A6CiAKIC0gYFN0dWR5LkFyZWFgOgogClRyYW5zZWN0b3MgcXVlIGZvcmFtIGFtb3N0cmFkb3MsIG1hcyBxdWUgbsOjbyB0aXZlcmFtIG9ic2VydmHDp8O1ZXMgKG4gPSAwKSBkZXZlbSBzZXIgaW5jbHXDrWRvcyBubyBjb25qdW50byBkZSBkYWRvcyBjb20gYE5BYCBuYXMgb2JzZXJ2YcOnw7VlcyBkZSBkaXN0w6JuY2lhIGUgcXVhbHF1ZXIgb3V0cmEgY292YXJpYWVsIHBhcmEgYSBxdWFsIG7Do28gc2UgdGVuaGEgb2JzZXJ2YcOnw6NvLgogCmBgYHtyfQojIGN1dGlhX3RhcF9hcmFwIHw+IAojICAgY29tcGxldGUoUmVnaW9uLkxhYmVsLCBTYW1wbGUuTGFiZWwsIHNwX25hbWUpIHw+IAojICAgZGF0YXRhYmxlKGZpbHRlciA9IGxpc3QocG9zaXRpb24gPSAidG9wIikpCmBgYAoKSm9nYXIgYSBpbXB1dGFjYW8gZGUgYE5BYHMgcHJhIGRlbnRybyBkYSBmdW5jYW8gY2FycmVnYXIgZGFkb3MgY29tcGxldG9zLgoKIyMgRGV0ZXJtaW5hbmRvIGEgZGlzdMOibmNpYSBwYXJhIHRydW5jYXIgb3MgZGFkb3MKCmBgYHtyLCBmaWcuaGVpZ2h0PTE1LCBmaWcud2lkdGg9MTAsIHdhcm5pbmc9RkFMU0V9CiMgZGVzZW5oYSBvIGdyYWZpY28gY29tIGEgZGlzdHJpYnVpY2FvIGRlIGRpc3RhbmNpYXMgcGVycGVuZGljdWxhcmVzCmN1dGlhX3RhcF9hcmFwIHw+IAogIGZpbHRlcihkaXN0YW5jZSA+PSAxLAogICAgICAgICBkaXN0YW5jZSA8PSAxNCkgfD4gCiAgcGxvdGFyX2Rpc3RyaWJ1aWNhb19kaXN0YW5jaWFfaW50ZXJhdGl2bygpCmBgYAoKYGBge3J9CnN1bW1hcnkoY3V0aWFfdGFwX2FyYXAkZGlzdGFuY2UpCmBgYAoKIAojIyBBanVzdGFuZG8gZnVuw6fDtWVzIGRlIGRldGVjw6fDo28gbm8gUgoKIyMjIEN1dGlhcyBkYSBSZXNleCBUYXBhasOzcy1BcmFwaXVucyBwYXJhIGRpZmVyZW50ZXMgZGlzdMOibmNpYXMgZGUgdHJ1bmNhbWVudG8KCiMjIyMgKkhhbGYtTm9ybWFsKiBzZW0gdGVybW9zIGRlIGFqdXN0ZSBlIGNvbSB0ZXJtb3MgZGUgYWp1c3RlIENvc3Nlbm8gZSBQb2xpbm9taWFsIGRlIEhlcm1pdGUKCkFqdXN0YW5kbyB1bSBtb2RlbG8gYW8gZGFkb3MgZGFzIGN1dGlhcyAqRGFzeXByb2N0YSBjcm9jb25vdGEqLCBjb25maWd1cmFuZG8gdW1hIGRpc3TDom5jaWEgbGltaXRlIGRlIDIwbSBlIHVzYW5kbyAqSGFsZi1ub3JtYWwqIGNvbW8gKmtleSBmdW5jdGlvbiogdXNhbmRvIG8gYXJndW1lbnRvIGBrZXlgLCBzZW0gdGVybW8gZGUgYWp1c3RlLgoKYGBge3J9CgpjdXRpYV90YXBfYXJhcF9maWx0cmFkbyA8LSBjdXRpYV90YXBfYXJhcCB8PiAKICBmaWx0ZXIoZGlzdGFuY2UgPj0gMSwKICAgICAgICAgZGlzdGFuY2UgPD0gMTQpCgojIGFqdXN0YW5kbyBhIGZ1bsOnw6NvIGRlIGRldGVjw6fDo28gcGFyYSB1bWEgZGlzdGFuY2lhIGRlIHRydW5jYW1lbnRvIGRlIDIwLCAxNSwgMTAgZSA1IG1ldHJvcwojIGRzaXRhbmNpYXMgZGUgdHJ1bmNhbWVudG8KZGlzdF90cnVuY2FtZW50byA8LSBsaXN0KAogIGAxNCBtZXRyb3NgID0gMTQsIAogIGAxMiBtZXRyb3NgID0gMTIsIAogIGAxMCBtZXRyb3NgID0gMTAsCiAgYDcgbWV0cm9zYCA9IDcKKQoKIyBLZXkgZnVuY3Rpb24gLSBIYWxmLW5vcm1hbCAKY3V0aWFfdGFwX2FyYXBfaG4gPC0gcHVycnI6Om1hcCgKICBkaXN0X3RydW5jYW1lbnRvLAogIFwoLngpIGFqdXN0ZV9tb2RlbG9zX2Rpc3RhbmNlX2huKAogICAgY3V0aWFfdGFwX2FyYXBfZmlsdHJhZG8sIAogICAgdHJ1bmNhbWVudG8gPSAueAogICkKICApCmBgYAoKYGBge3J9CmN1dGlhX3RhcF9hcmFwX2huCmBgYAoKIyMjIyAqSGF6YXJkLVJhdGUqIHNlbSB0ZXJtb3MgZGUgYWp1c3RlIGUgY29tIHRlcm1vcyBkZSBhanVzdGUgQ29zc2VubyBlIFBvbGlub21pYWwgZGUgSGVybWl0ZQoKQWp1c3RhbmRvIHVtIG1vZGVsbyBhbyBkYWRvcyBkYSBjdXRpYSAqRGFzeXByb2N0YSBjcm9jb25vdGEqLCBjb25maWd1cmFuZG8gdW1hIGRpc3TDom5jaWEgbGltaXRlIGRlIDIwbSBlIHVzYW5kbyAqSGF6YXJkIHJhdGUqIGNvbW8gKmtleSBmdW5jdGlvbiogdXNhbmRvIG8gYXJndW1lbnRvIGBrZXlgLgoKYGBge3J9CiMgYWp1c3RhbmRvIGEgZnVuw6fDo28gZGUgZGV0ZWPDp8OjbyBwYXJhIHVtYSBkaXN0YW5jaWEgZGUgdHJ1bmNhbWVudG8gZGUgMjAsIDE1LCAxMCBlIDUgbWV0cm9zCiMgS2V5IGZ1bmN0aW9uIC0gSGF6YXJkLXJhdGUKY3V0aWFfdGFwX2FyYXBfaHIgPC0gcHVycnI6Om1hcCgKICBkaXN0X3RydW5jYW1lbnRvLAogIFwoLngpIGFqdXN0ZV9tb2RlbG9zX2Rpc3RhbmNlX2hyKAogICAgY3V0aWFfdGFwX2FyYXBfZmlsdHJhZG8sIAogICAgdHJ1bmNhbWVudG8gPSAueAogICkKICApCmBgYAoKIyMjIyAqVW5pZm9ybSogc2VtIHRlcm1vcyBkZSBhanVzdGUgZSBjb20gdGVybW9zIGRlIGFqdXN0ZSBDb3NzZW5vIGUgUG9saW5vbWlhbCBkZSBIZXJtaXRlCgpBanVzdGFuZG8gdW0gbW9kZWxvIGFvIGRhZG9zIGRhcyBjdXRpYXMgKkRhc3lwcm9jdGEgY3JvY29ub3RhKiwgY29uZmlndXJhbmRvIHVtYSBkaXN0w6JuY2lhIGxpbWl0ZSBkZSAyMG0gZSB1c2FuZG8gKlVuaWZvcm0qIGNvbW8gKmtleSBmdW5jdGlvbiogdXNhbmRvIG8gYXJndW1lbnRvIGBrZXlgLCBzZW0gdGVybW8gZGUgYWp1c3RlLgoKYGBge3J9CiMgYWp1c3RhbmRvIGEgZnVuw6fDo28gZGUgZGV0ZWPDp8OjbyBwYXJhIHVtYSBkaXN0YW5jaWEgZGUgdHJ1bmNhbWVudG8gZGUgMjAsIDE1LCAxMCBlIDUgbWV0cm9zCiMgS2V5IGZ1bmN0aW9uIC0gVW5pZm9ybQpjdXRpYV90YXBfYXJhcF91bmlmIDwtIHB1cnJyOjptYXAoCiAgZGlzdF90cnVuY2FtZW50bywKICBcKC54KSBhanVzdGVfbW9kZWxvc19kaXN0YW5jZV91bmlmKAogICAgY3V0aWFfdGFwX2FyYXAsIAogICAgdHJ1bmNhbWVudG8gPSAueAogICkKKQpgYGAKCiMjIyMjIyBTZWxlw6fDo28gZGUgbW9kZWxvcwoKYGBge3J9CnN1bW1hcml6ZV9kc19tb2RlbHMoCiAgY3V0aWFfdGFwX2FyYXBfaG4kYDE0IG1ldHJvc2AkYFNlbSB0ZXJtb2AsCmN1dGlhX3RhcF9hcmFwX2huJGAxNCBtZXRyb3NgJENvc3Nlbm8sCiAgY3V0aWFfdGFwX2FyYXBfaG4kYDE0IG1ldHJvc2AkYEhlcm1pdGUgcG9saW5vbWlhbGAsCmN1dGlhX3RhcF9hcmFwX2hyJGAxNCBtZXRyb3NgJGBTZW0gdGVybW9gLApjdXRpYV90YXBfYXJhcF9ociRgMTQgbWV0cm9zYCRDb3NzZW5vLApjdXRpYV90YXBfYXJhcF9ociRgMTQgbWV0cm9zYCRgUG9saW5vbWlhbCBzaW1wbGVzYCwKY3V0aWFfdGFwX2FyYXBfdW5pZiRgMTQgbWV0cm9zYCRDb3NzZW5vLApjdXRpYV90YXBfYXJhcF91bmlmJGAxNCBtZXRyb3NgJGBQb2xpbm9taWFsIHNpbXBsZXNgCikKYGBgCgpgYGB7cn0Kc3VtbWFyaXplX2RzX21vZGVscygKICBjdXRpYV90YXBfYXJhcF9obiRgMTIgbWV0cm9zYCRgU2VtIHRlcm1vYCwKY3V0aWFfdGFwX2FyYXBfaG4kYDEyIG1ldHJvc2AkQ29zc2VubywKICBjdXRpYV90YXBfYXJhcF9obiRgMTIgbWV0cm9zYCRgSGVybWl0ZSBwb2xpbm9taWFsYCwKY3V0aWFfdGFwX2FyYXBfaHIkYDEyIG1ldHJvc2AkYFNlbSB0ZXJtb2AsCmN1dGlhX3RhcF9hcmFwX2hyJGAxMiBtZXRyb3NgJENvc3Nlbm8sCmN1dGlhX3RhcF9hcmFwX2hyJGAxMiBtZXRyb3NgJGBQb2xpbm9taWFsIHNpbXBsZXNgLApjdXRpYV90YXBfYXJhcF91bmlmJGAxMiBtZXRyb3NgJENvc3Nlbm8sCmN1dGlhX3RhcF9hcmFwX3VuaWYkYDEyIG1ldHJvc2AkYFBvbGlub21pYWwgc2ltcGxlc2AKKQpgYGAKCmBgYHtyfQpzdW1tYXJpemVfZHNfbW9kZWxzKAogIGN1dGlhX3RhcF9hcmFwX2huJGAxMCBtZXRyb3NgJGBTZW0gdGVybW9gLApjdXRpYV90YXBfYXJhcF9obiRgMTAgbWV0cm9zYCRDb3NzZW5vLAogIGN1dGlhX3RhcF9hcmFwX2huJGAxMCBtZXRyb3NgJGBIZXJtaXRlIHBvbGlub21pYWxgLApjdXRpYV90YXBfYXJhcF9ociRgMTAgbWV0cm9zYCRgU2VtIHRlcm1vYCwKY3V0aWFfdGFwX2FyYXBfaHIkYDEwIG1ldHJvc2AkQ29zc2VubywKY3V0aWFfdGFwX2FyYXBfaHIkYDEwIG1ldHJvc2AkYFBvbGlub21pYWwgc2ltcGxlc2AsCmN1dGlhX3RhcF9hcmFwX3VuaWYkYDEwIG1ldHJvc2AkQ29zc2VubywKY3V0aWFfdGFwX2FyYXBfdW5pZiRgMTAgbWV0cm9zYCRgUG9saW5vbWlhbCBzaW1wbGVzYAopCmBgYAoKYGBge3J9CnN1bW1hcml6ZV9kc19tb2RlbHMoCiAgY3V0aWFfdGFwX2FyYXBfaG4kYDcgbWV0cm9zYCRgU2VtIHRlcm1vYCwKY3V0aWFfdGFwX2FyYXBfaG4kYDcgbWV0cm9zYCRDb3NzZW5vLAogIGN1dGlhX3RhcF9hcmFwX2huJGA3IG1ldHJvc2AkYEhlcm1pdGUgcG9saW5vbWlhbGAsCmN1dGlhX3RhcF9hcmFwX2hyJGA3IG1ldHJvc2AkYFNlbSB0ZXJtb2AsCmN1dGlhX3RhcF9hcmFwX2hyJGA3IG1ldHJvc2AkQ29zc2VubywKY3V0aWFfdGFwX2FyYXBfaHIkYDcgbWV0cm9zYCRgUG9saW5vbWlhbCBzaW1wbGVzYCwKY3V0aWFfdGFwX2FyYXBfdW5pZiRgNyBtZXRyb3NgJENvc3Nlbm8sCmN1dGlhX3RhcF9hcmFwX3VuaWYkYDcgbWV0cm9zYCRgUG9saW5vbWlhbCBzaW1wbGVzYAopCmBgYAoKIyMjIyBSZXN1bWlyIG8gcmVzdWx0YWRvIGRvcyBtb2RlbG9zCgpPIHF1ZSB0ZW0gcXVlIHRlcj8KCk9zIGdyw6FmaWNvcyAocHJvYmFiaWxpZGFkZSBkZSBkZXRlY8Onw6NvIHBlbGEgZGlzdMOibmNpYSwgY29tIGEgY3VydmEgYWp1c3RhZGEsIGV4ZW1wbG8gYWJhaXhvLCBmYXplciBubyBnZ3Bsb3QpLCByZXN1bHRhZG8gZG8gZ29vZG5lc3Mgb2YgZml0IChnb2ZfZHMoKSksIGNhZGEgbW9kZWxvIHZhaSB0ZXIgcXVlIHRlciB1bSBub21lIGRpZmVyZW50ZSBudW1hIHRhYmVsYSg/KQoKYGBge3J9CnBsb3QoY3V0aWFfdGFwX2FyYXBfaG4sIGJyZWFrcyA9IHNlcSgwLCAyMCwgMi41KSkKcGxvdChjdXRpYV90YXBfYXJhcF9obl9oZXJtLCBicmVha3MgPSBzZXEoMCwgMjAsIDIuNSkpCnBsb3QoY3V0aWFfdGFwX2FyYXBfaG5fY29zLCBicmVha3MgPSBzZXEoMCwgMjAsIDIuNSkpCnBsb3QoY3V0aWFfdGFwX2FyYXBfaHIsIGJyZWFrcyA9IHNlcSgwLCAyMCwgMi41KSkKcGxvdChjdXRpYV90YXBfYXJhcF9ocl9wb2x5LCBicmVha3MgPSBzZXEoMCwgMjAsIDIuNSkpCnBsb3QoY3V0aWFfdGFwX2FyYXBfaHJfY29zLCBicmVha3MgPSBzZXEoMCwgMjAsIDIuNSkpCmBgYAoKIyMgQ2hlY2FnZW0gZSBzZWxlw6fDo28gZGUgbW9kZWxvcwoKUG9kZW1vcyB1c2FyIGEgZnVuw6fDo28gYHN1bW1hcnlgIHBhcmEgb2J0ZXIgaW5mb3JtYcOnw7VlcyBpbXBvcnRhbnRlcyBzb2JyZSBvIG1vZGVsby4KCmBgYHtyfQoKbGlzdGFfbW9kZWxvcyA8LSBsaXN0KAogIGN1dGlhX3RhcF9hcmFwX2huLAogIGN1dGlhX3RhcF9hcmFwX2huX2hlcm0sCiAgY3V0aWFfdGFwX2FyYXBfaG5fY29zLAogIGN1dGlhX3RhcF9hcmFwX2hyLAogIGN1dGlhX3RhcF9hcmFwX2hyX3BvbHksCiAgY3V0aWFfdGFwX2FyYXBfaHJfY29zCikKCnB1cnJyOjptYXAobGlzdGFfbW9kZWxvcywgXCh4KSBzdW1tYXJ5KHgpKQpgYGAKCmBgYHtyfQpzdW1tYXJpemVfZHNfbW9kZWxzKAogIGN1dGlhX3RhcF9hcmFwX2huLAogIGN1dGlhX3RhcF9hcmFwX2huX2hlcm0sCiAgY3V0aWFfdGFwX2FyYXBfaG5fY29zLAogIGN1dGlhX3RhcF9hcmFwX2hyLAogIGN1dGlhX3RhcF9hcmFwX2hyX3BvbHksCiAgY3V0aWFfdGFwX2FyYXBfaHJfY29zCikKCgpgYGAKCgoKTyByZXN1bHRhZG8gIGluY2x1aSBkZXRhbGhlcyBzb2JyZSBvIGRhZG8gZSBhIGVzcGVjaWZpY2HDp8OjbyBkbyBtb2RlbG8sIGFzc2ltIGNvbW8gZG9zIGNvZWZpY2llbnRlcyAoJFxiZXRhX3tqfSQpIGUgc3VhIGluY2V0ZXphLCBhIG3DqWRpYSBkbyB2YWxvciBkZSBkZXRlY3RhYmlsaWRhZGUgZSBzdWEgaW5jZXJ0ZXphIGUgdW1hIGVzdGltYXRpdmEgZGEgYWJ1bmTDom5jaWEgbmEgw6FyZWEgY29iZXJ0YSBwZWxhIGFtb3N0cmFnZW0gKHNlbSBsZXZhciBlbSBjb25zaWRlcmHDp8OjbyBvIHRhbWFuaG8gZG9zIGFncnVwYW1lbnRvcywgb3UgYmFuZG9zKS4gCgojIyMgQm9uZGFkZSBkZSBhanVzdGUKClBhcmEgdmlzdWFsaXphciBxdcOjbyBiZW0gYSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvIHNlIGFqdXN0YSBhb3MgZGFkb3MgcXVhbnRvIHRlbW9zIGFzIGRpc3TDom5jaWFzIGV4YXRhcyBwb2RlbW9zIHVzYXIgdW0gcGxvdCBkZSBxdWFudGlzIGVtcMOtcmljb3MgeCB0ZcOzcmljb3MgKFEtUSBwbG90KS4gRWxlIGNvbXBhcmEgYSBmdW7Dp8OjbyBkZSBkaXN0cmlidWnDp8OjbyBjdW11bGF0aXZhIChDREYpIGRvcyB2YWxvcmVzIGFqdXN0YWRvcyBkYSBmdW7Dp8OjbyBkZXRlY8Onw6NvIGEgZGlzdHJpYnVpw6fDo28gZW1ww61yaWNhIGRvcyBkYWRvcyAoRURGKS4gCgpUYW1iw6ltIHBvZGVtb3MgdXNhciBvIHRlc3RlIGRlIENyYW3DqXItdm9uIE1pc2VzIHBhcmEgdGVzdGFyIHNlIG9zIHBvbnRvcyBkYSBFREYgZSBkYSBDREYgdGVtIG9yaWdlbSBuYSBtZXNtYSBkaXN0cmlidWnDp8Ojby4gTyB0ZXN0ZSB1c2EgYSBzb21hIGRlIHRvZGFzIGFzIGRpc3TDom5jaWFzIGVudHJlIHVtIHBvbnRvIGUgYSBsaW5oYSB5ID0geCBwYXJhIGZvcm1hciBhIGVzdGF0w61zdGljYSBhIHNlciB0ZXN0YWRhLiBVbSByZXN1bHRhZG8gc2lnbmlmaWNhdGl2byBmb3JuZWNlIGV2aWTDqm5jaWEgY29udHJhIGEgaGlpcMOzdGVzZSBudWxhLCBzdWdlcmluZG8gcXVlIG8gbW9kZWxvIG7Do28gc2UgYWp1c3RhIGJlbSBhb3MgZGFkb3MuCgpgYGB7cn0KIyBhanVzdGFuZG8gdW0gbW9kZWxvIEhhbGYtbm9ybWFsCmN1dGlhX2huIDwtIGRzKGRhdGEgPSBjdXRpYV90YXBfYXJhcF8xNSwKICAgICAgICAgICAgICAgICB0cnVuY2F0aW9uID0gMjAsCiAgICAgICAgICAgICAgICAgdHJhbnNlY3QgPSAibGluZSIsCiAgICAgICAgICAgICAgICAga2V5ID0gImhuIiwgCiAgICAgICAgICAgICAgICAgYWRqdXN0bWVudCA9IE5VTEwpCgojIGNvbmR1emluZG8gbyB0ZXN0ZSBkZmUgYm9uZGFkZWRlIGFqdXN0ZSBkZSBDcmFtZXItdm9uIE1pc2VzCmdvZl9kcyhjdXRpYV9obikKCmdvZl9kcyhjdXRpYV9ocl90aW1lKQpgYGAKCk8gcmVzdXRsYWRvIGRvIHRlc3RlIGFwb250YSBxdWUgbyBtb2RlbG8gKkhhbGYtbm9ybWFsKiBkZXZlIHNlciBkZXNjYXJ0YWRvLgoKVGVzdGVzIGRlIGJvbmRhZGUgZGUgYWp1c3RlIGRlIGNoaS1xdWFkcmFkbyBzw6NvIGdlcmFkb3MgdXNhbmRvIGEgZnVuw6fDo28gYGdvZl9kc2AgcXVhbmRvIGFzIGRpc3TDom5jaWFzIGZvcm5lY2VpZGFzIGVzdMOjbyBjYXRlZ29yaXphZGFzLgoKIyMjIFNlbGXDp8OjbyBkZSBNb2RlbG9zCgpVbWEgdmV6IHF1ZSB0ZW1vcyB1bSBjb25qdW50byBkZSBtb2RlbG9zIHBsYXVzw612ZWlzLCBwb2RlbW9zIHV0aWxpemFyIG8gY2lydMOpcmlvZGUgaW5mb3JtYcOnw6NvZGUgQWthaWtlIChBSUMpIHBhcmEgc2VsZWNpb25hciBlbnRyZSBvcyBtb2RlbG9zIG8gcXVlIG1lbGhvciBzZSBhanVzdGEgYW9zIGRhZG9zIHV0aWxpemFuZG8gYSBmdW7Dp8OjbyBgc3VtbWFyaXplX2RzX21vZGVsc2AuCgpgYGB7cn0KIyBnZXJhbmRvIHVtYSB0YWJlbGEgZGUgc2VsZcOnw6NvIGRlIG1vZGVsb3MgdXNhbmRvIEFJQwpzdW1tYXJpemVfZHNfbW9kZWxzKGN1dGlhX2huLCBjdXRpYV9ocl90aW1lLCBjdXRpYV9ocl90aW1lX3NpemUpCmBgYAoKTyBtZWxob3IgbW9kZWxvIMOpIG8gSGF6YXJkLXJhdGUgY29tIHRlbXBvIGRlIHNlbnNvIGUgdGFtYW5obyBkbyBncnVwbyBjb21vIGNvdmFyacOhdmVpcy4KCiMjIEVzdGltYW5kbyBhIGFidW5kw6JuY2lhIGUgYSB2YXJpw6JuY2lhCgojIyMgRXN0aW1hbmRvIGFidW5kw6JuY2lhIGUgdmFyacOibmNpYSBubyBSCgpQYXJhIG9idGVyIGEgYWJ1bmTDom5jaWEgbmEgcmVnacOjbyBkZSBlc3R1ZG8sIHByaW1laXJvIGNhbGN1bGFtb3MgYSBhYnVuZMOibmNpYSBuYSDDoXJlYSBhbW9zdHJhZGEgcGFyYSBvYnRlciAkTl9jJCBlIGVtIHNlZ3VpZGEgZXNjYWxvbmFtb3MgZXNzZSB2YWxvciBwYXJhIHRvZGEgYSDDoXJlYSBkZSBlc3R1ZG8gbXVsdGlwbGljYW5kbyAkTl9jJCBwZWxhIHJhesOjbyBlbnRyZSBhIMOhcmVhIGFtb3N0cmFkYSBlIGEgw6FyZWEgZGEgcmVnacOjby4gUGFyYSBlc3RpbWFyIGEgYWJ1bmTDom5jaWEgbmEgw6FyZWEgYW1vc3RyYWRhLCB1dGlsaXphbW9zIGFzIGVzdGltYXRpdmFzIGRlIHByb2JhYmlsaWRhZGUgZGUgZGV0ZWPDp8OjbyBubyBlc3RpbWFkb3IgZGUgSG9ydml0ei1UaG9tcHNvbi4KClF1YW5kbyBmb3JuZWNlbW9zIG9zIGRhZG9zIG5vIGZvcm1hdG8gY29ycmV0byAoImZsYXRmaWxlIikgYGRzYCBpcsOhIGF1dG9tYXRpY2FtZW50ZSBjYWxjdWxhciBhcyBlc3RpbWF0aXZhcyBkZSBhYnVuZMOibmNpYSBiYXNlYWRvIG5hcyBpbmZvcm1hw6fDtWVzIGRlIGFtb3N0cmFnZW0gcHJlc2VudGEgbm9zIGRhZG9zLgoKYGBge3J9CnN1bW1hcnkoY3V0aWFfaG4pCmBgYAoKMS4gU3VtbWFyeSBzdGF0aXN0aWNzOiBmb3JuZWNlIGFzIMOhcmVhcywgYcWVZWEgZGUgYW1vc3RyYWdlbSwgZXNmb3LDp28sIG7Dum1lcm8gZGUgb2JzZXJ2YcOnw7VlcywgbsO6bWVybyBkZSB0cmFuc2VjdG9zLCB0YXhhIGRlIGVuY29udHJvLCBzZXVzIGVycm9zIHBhZHLDtWVzIGUgY29lZmljaWVudGVzIGRlIHZhcmlhw6fDo28gcGFyYSBjYWRhIGVzdHJhdG87CgoyLiBBYnVuZGFuY2U6IGZvcm5lY2UgZXN0aW1hdGl2YXMsIGVycm9zIHBhZHLDtWVzLCBjb2VmaWNpZW50ZXNkZSB2YXJpYcOnw6NvLCBpbnRlcnZhbG9zIGRlIGNvbmZpYW7Dp2EgaW5mZXJpb3IgZSBzdXBlcmlvciwgZ3JhdXMgZGUgbGliZXJkYWRlIHBhcmEgYSBlc3RpbWF0aXZhIGRlIGFidW5kw6JuY2lhIGRlIGNhZGEgZXN0cmF0bzsKCjMuIERlbnNpZGFkZTogbGlzdGEgYXMgbWVzbWFzIGVzdGF0w61zdGljYXMgZGUgQWJ1bmRhbmNlLCBzw7MgcXVlIHBhcmEgZGVuc2lkYWRlLgoKIyMgKipGdW7Dp8O1ZXMgRXhwbG9yYXTDs3JpYXMgQWRpY2lvbmFpcyoqCgpgY29udGFyX25fcmVwZXRpY29lc190cmlsaGEoKWAgLSBjb250YSBvIG7Dum1lcm8gZGUgdmV6ZXMgcXVlIGNhZGEgdHJpbGhhIGZvaSB2aXNpdGFkYQoKIyMgQWRpY2lvbmFuZG8gY292YXJpYXZlbAoKQWp1c3RlICpIZXJtaXRlIHBvbGx5bm9taWFsKiB1c2Egb2QgY8OzZGlnbyBgImhlcm0iYCBlIHBvbGlub21pYWwgc2ltcGxlcyBgInBvbHkiYC4KClBvZGVtb3MgaW5jbHVpciBjb3ZhcmnDoXZlaXMgdXRpbGl6YW5kbyBvIGFyZ3VtZW50byBgZm9ybXVsYSA9IH4gLi4uYC4gQWJhaXhvLCBlc3TDoSBlc3BlY2lmaWNhZG8gdW0gbW9kZWxvICJIYXphcmQtcmF0ZSIgcGFyYSBvcyBkYWRvcyBkZSBjdXRpYSBxIHVlIGluY2x1aSBvIHRlbXBvIGRlIHNlbnNvIGNvbW8gY292YXJpw6F2ZWwgZSB1bWEgZGlzdMOibmNpYSBsaW1pdGUgZGUgMjBtLgoKYGBge3J9CmN1dGlhX2hyX3RpbWUgPC0gY3V0aWFfdGFwX2FyYXBfMTUgfD4gCiAgZHModHJ1bmNhdGlvbiA9IDIwLAogICAgIGtleSA9ICJociIsCiAgICAgZm9ybXVsYSA9IH4gY2Vuc2VfdGltZSkKYGBgCgpBZGljaW9uYW5kbyB1bWEgc2VndW5kYSBjb3ZhcmnDoXZlbDogdGFtYW5obyBkbyBncnVwby4KCmBgYHtyfQpjdXRpYV9ocl90aW1lX3NpemUgPC0gZHMoZGF0YSA9IGN1dGlhX3RhcF9hcmFwXzE1LAogICAgICAgICAgICAgICAgICAgICB0cnVuY2F0aW9uID0gMjAsCiAgICAgICAgICAgICAgICAgICAgIHRyYW5zZWN0ID0gImxpbmUiLAogICAgICAgICAgICAgICAgICAgICBrZXkgPSAiaHIiLAogICAgICAgICAgICAgICAgICAgICBmb3JtdWxhID0gfiBjZW5zZV90aW1lICsgc2l6ZSkKYGBgCgpgYGB7cn0KcGxvdChjdXRpYV9ocl90aW1lKQpwbG90KGN1dGlhX2hyX3RpbWVfc2l6ZSkKYGBgCgojIyMgQ3V0aWFzIGRhIEVTRUMgVGVycmEgZG8gTWVpbyBwYXJhIGRpZmVyZW50ZXMgZGlzdMOibmNpYXMgZGUgdHJ1bmNhbWVudG8KCmBgYHtyfQpjdXRpYV9lc2VjX3RlcnJhX21laW8gPC0gdHJhbnNmb3JtYXJfcGFyYV9kaXN0YW5jZVJfY292YXJpYXZlaXMoKSB8PiAKICBmaWx0ZXIoCiAgICBSZWdpb24uTGFiZWwgPT0gIkVzZWMgZGEgVGVycmEgZG8gTWVpbyIsCiAgICBzcF9uYW1lID09ICJEYXN5cHJvY3RhIGNyb2Nvbm90YSIKICApIHw+IAogIGRyb3BfbmEoZGlzdGFuY2UpCiAgCmBgYAoKYGBge3J9CiMgZGVzZW5oYSBvIGdyYWZpY28gY29tIGEgZGlzdHJpYnVpY2FvIGRlIGRpc3RhbmNpYXMgcGVycGVuZGljdWxhcmVzCmN1dGlhX2VzZWNfdGVycmFfbWVpbyB8PiAKICBmaWx0ZXIoZGlzdGFuY2UgPj0gMSwKICAgICAgICAgZGlzdGFuY2UgPCAxNSkgfD4gCiAgcGxvdGFyX2Rpc3RyaWJ1aWNhb19kaXN0YW5jaWFfaW50ZXJhdGl2byhsYXJndXJhX2NhaXhhID0gMSkKYGBgCgojIyMjICpIYWxmLU5vcm1hbCogc2VtIHRlcm1vcyBkZSBhanVzdGUgZSBjb20gdGVybW9zIGRlIGFqdXN0ZSBDb3NzZW5vIGUgUG9saW5vbWlhbCBkZSBIZXJtaXRlCgpBanVzdGFuZG8gdW0gbW9kZWxvIGFvIGRhZG9zIGRhcyBjdXRpYXMgKkRhc3lwcm9jdGEgY3JvY29ub3RhKiwgY29uZmlndXJhbmRvIHVtYSBkaXN0w6JuY2lhIGxpbWl0ZSBkZSAyMG0gZSB1c2FuZG8gKkhhbGYtbm9ybWFsKiBjb21vICprZXkgZnVuY3Rpb24qIHVzYW5kbyBvIGFyZ3VtZW50byBga2V5YCwgc2VtIHRlcm1vIGRlIGFqdXN0ZS4KCmBgYHtyfQpjdXRpYV9lc2VjX3RlcnJhX21laW9fZmlsdHJhZG8KYGBgCgoKYGBge3J9CmN1dGlhX2VzZWNfdGVycmFfbWVpb19maWx0cmFkbyA8LSBjdXRpYV9lc2VjX3RlcnJhX21laW8gfD4gCiAgZmlsdGVyKGRpc3RhbmNlID49IDEsCiAgICAgICAgIGRpc3RhbmNlIDwgMTUpCiMgYWp1c3RhbmRvIGEgZnVuw6fDo28gZGUgZGV0ZWPDp8OjbyBwYXJhIHVtYSBkaXN0YW5jaWEgZGUgdHJ1bmNhbWVudG8gZGUgMjAsIDE1LCAxMCBlIDUgbWV0cm9zCiMgZHNpdGFuY2lhcyBkZSB0cnVuY2FtZW50bwpkaXN0X3RydW5jYW1lbnRvIDwtIGxpc3QoCiAgI2AyMCBtZXRyb3NgID0gMjAsIAogIGAxNSBtZXRyb3NgID0gMTUsIAogIGAxMiBtZXRyb3NgID0gMTIsCiAgYDEwIG1ldHJvc2AgPSAxMAopCgojIEtleSBmdW5jdGlvbiAtIEhhbGYtbm9ybWFsIApjdXRpYV9lc2VjX3RlcnJhX21laW9faG4gPC0gcHVycnI6Om1hcCgKICBkaXN0X3RydW5jYW1lbnRvLAogIFwoLngpIGFqdXN0ZV9tb2RlbG9zX2Rpc3RhbmNlX2huKAogICAgY3V0aWFfZXNlY190ZXJyYV9tZWlvX2ZpbHRyYWRvLCAKICAgIHRydW5jYW1lbnRvID0gLngKICApCiAgKQpgYGAKCmBgYHtyfQpjdXRpYV9lc2VjX3RlcnJhX21laW9faG4KYGBgCgojIyMjICpIYXphcmQtUmF0ZSogc2VtIHRlcm1vcyBkZSBhanVzdGUgZSBjb20gdGVybW9zIGRlIGFqdXN0ZSBDb3NzZW5vIGUgUG9saW5vbWlhbCBkZSBIZXJtaXRlCgpBanVzdGFuZG8gdW0gbW9kZWxvIGFvIGRhZG9zIGRhIGN1dGlhICpEYXN5cHJvY3RhIGNyb2Nvbm90YSosIGNvbmZpZ3VyYW5kbyB1bWEgZGlzdMOibmNpYSBsaW1pdGUgZGUgMjBtIGUgdXNhbmRvICpIYXphcmQgcmF0ZSogY29tbyAqa2V5IGZ1bmN0aW9uKiB1c2FuZG8gbyBhcmd1bWVudG8gYGtleWAuCgpgYGB7cn0KIyBhanVzdGFuZG8gYSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvIHBhcmEgdW1hIGRpc3RhbmNpYSBkZSB0cnVuY2FtZW50byBkZSAyMCwgMTUsIDEwIGUgNSBtZXRyb3MKIyBLZXkgZnVuY3Rpb24gLSBIYXphcmQtcmF0ZQpjdXRpYV9lc2VjX3RlcnJhX21laW9faHIgPC0gcHVycnI6Om1hcCgKICBkaXN0X3RydW5jYW1lbnRvLAogIFwoLngpIGFqdXN0ZV9tb2RlbG9zX2Rpc3RhbmNlX2hyKAogICAgY3V0aWFfZXNlY190ZXJyYV9tZWlvX2ZpbHRyYWRvLCAKICAgIHRydW5jYW1lbnRvID0gLngKICApCiAgKQpgYGAKCiMjIyMgKlVuaWZvcm0qIHNlbSB0ZXJtb3MgZGUgYWp1c3RlIGUgY29tIHRlcm1vcyBkZSBhanVzdGUgQ29zc2VubyBlIFBvbGlub21pYWwgZGUgSGVybWl0ZQoKQWp1c3RhbmRvIHVtIG1vZGVsbyBhbyBkYWRvcyBkYXMgY3V0aWFzICpEYXN5cHJvY3RhIGNyb2Nvbm90YSosIGNvbmZpZ3VyYW5kbyB1bWEgZGlzdMOibmNpYSBsaW1pdGUgZGUgMjBtIGUgdXNhbmRvICpVbmlmb3JtKiBjb21vICprZXkgZnVuY3Rpb24qIHVzYW5kbyBvIGFyZ3VtZW50byBga2V5YCwgc2VtIHRlcm1vIGRlIGFqdXN0ZS4KCmBgYHtyfQojIGFqdXN0YW5kbyBhIGZ1bsOnw6NvIGRlIGRldGVjw6fDo28gcGFyYSB1bWEgZGlzdGFuY2lhIGRlIHRydW5jYW1lbnRvIGRlIDIwLCAxNSwgMTAgZSA1IG1ldHJvcwojIEtleSBmdW5jdGlvbiAtIFVuaWZvcm0KY3V0aWFfZXNlY190ZXJyYV9tZWlvX3VuaWYgPC0gcHVycnI6Om1hcCgKICBkaXN0X3RydW5jYW1lbnRvLAogIFwoLngpIGFqdXN0ZV9tb2RlbG9zX2Rpc3RhbmNlX3VuaWYoCiAgICBjdXRpYV90YXBfYXJhcCwgCiAgICB0cnVuY2FtZW50byA9IC54CiAgKQogICkKYGBgCgojIyMjIyMgU2VsZcOnw6NvIGRlIG1vZGVsb3MKCmBgYHtyfQpzdW1tYXJpemVfZHNfbW9kZWxzKAogIGN1dGlhX2VzZWNfdGVycmFfbWVpb19obiRgMjAgbWV0cm9zYCRgU2VtIHRlcm1vYCwKY3V0aWFfZXNlY190ZXJyYV9tZWlvX2huJGAyMCBtZXRyb3NgJENvc3Nlbm8sCiAgY3V0aWFfZXNlY190ZXJyYV9tZWlvX2huJGAyMCBtZXRyb3NgJGBIZXJtaXRlIHBvbGlub21pYWxgLApjdXRpYV9lc2VjX3RlcnJhX21laW9faHIkYDIwIG1ldHJvc2AkYFNlbSB0ZXJtb2AsCmN1dGlhX2VzZWNfdGVycmFfbWVpb19ociRgMjAgbWV0cm9zYCRDb3NzZW5vLApjdXRpYV9lc2VjX3RlcnJhX21laW9faHIkYDIwIG1ldHJvc2AkYFBvbGlub21pYWwgc2ltcGxlc2AsCmN1dGlhX2VzZWNfdGVycmFfbWVpb191bmlmJGAyMCBtZXRyb3NgJENvc3Nlbm8sCmN1dGlhX2VzZWNfdGVycmFfbWVpb191bmlmJGAyMCBtZXRyb3NgJGBQb2xpbm9taWFsIHNpbXBsZXNgCikKYGBgCgpgYGB7cn0Kc3VtbWFyaXplX2RzX21vZGVscygKICBjdXRpYV9lc2VjX3RlcnJhX21laW9faG4kYDE1IG1ldHJvc2AkYFNlbSB0ZXJtb2AsCmN1dGlhX2VzZWNfdGVycmFfbWVpb19obiRgMTUgbWV0cm9zYCRDb3NzZW5vLAogIGN1dGlhX2VzZWNfdGVycmFfbWVpb19obiRgMTUgbWV0cm9zYCRgSGVybWl0ZSBwb2xpbm9taWFsYCwKY3V0aWFfZXNlY190ZXJyYV9tZWlvX2hyJGAxNSBtZXRyb3NgJGBTZW0gdGVybW9gLApjdXRpYV9lc2VjX3RlcnJhX21laW9faHIkYDE1IG1ldHJvc2AkQ29zc2VubywKY3V0aWFfZXNlY190ZXJyYV9tZWlvX2hyJGAxNSBtZXRyb3NgJGBQb2xpbm9taWFsIHNpbXBsZXNgLApjdXRpYV9lc2VjX3RlcnJhX21laW9fdW5pZiRgMTUgbWV0cm9zYCRDb3NzZW5vLApjdXRpYV9lc2VjX3RlcnJhX21laW9fdW5pZiRgMTUgbWV0cm9zYCRgUG9saW5vbWlhbCBzaW1wbGVzYAopCmBgYAoKYGBge3J9CnN1bW1hcml6ZV9kc19tb2RlbHMoCiAgY3V0aWFfZXNlY190ZXJyYV9tZWlvX2huJGAxMCBtZXRyb3NgJGBTZW0gdGVybW9gLApjdXRpYV9lc2VjX3RlcnJhX21laW9faG4kYDEwIG1ldHJvc2AkQ29zc2VubywKICBjdXRpYV9lc2VjX3RlcnJhX21laW9faG4kYDEwIG1ldHJvc2AkYEhlcm1pdGUgcG9saW5vbWlhbGAsCmN1dGlhX2VzZWNfdGVycmFfbWVpb19ociRgMTAgbWV0cm9zYCRgU2VtIHRlcm1vYCwKY3V0aWFfZXNlY190ZXJyYV9tZWlvX2hyJGAxMCBtZXRyb3NgJENvc3Nlbm8sCmN1dGlhX2VzZWNfdGVycmFfbWVpb19ociRgMTAgbWV0cm9zYCRgUG9saW5vbWlhbCBzaW1wbGVzYCwKY3V0aWFfZXNlY190ZXJyYV9tZWlvX3VuaWYkYDEwIG1ldHJvc2AkQ29zc2VubywKY3V0aWFfZXNlY190ZXJyYV9tZWlvX3VuaWYkYDEwIG1ldHJvc2AkYFBvbGlub21pYWwgc2ltcGxlc2AKKQpgYGAKCmBgYHtyfQpzdW1tYXJpemVfZHNfbW9kZWxzKAogIGN1dGlhX2VzZWNfdGVycmFfbWVpb19obiRgMTIgbWV0cm9zYCRgU2VtIHRlcm1vYCwKY3V0aWFfZXNlY190ZXJyYV9tZWlvX2huJGAxMiBtZXRyb3NgJENvc3Nlbm8sCiAgY3V0aWFfZXNlY190ZXJyYV9tZWlvX2huJGAxMiBtZXRyb3NgJGBIZXJtaXRlIHBvbGlub21pYWxgLApjdXRpYV9lc2VjX3RlcnJhX21laW9faHIkYDEyIG1ldHJvc2AkYFNlbSB0ZXJtb2AsCmN1dGlhX2VzZWNfdGVycmFfbWVpb19ociRgMTIgbWV0cm9zYCRDb3NzZW5vLApjdXRpYV9lc2VjX3RlcnJhX21laW9faHIkYDEyIG1ldHJvc2AkYFBvbGlub21pYWwgc2ltcGxlc2AsCmN1dGlhX2VzZWNfdGVycmFfbWVpb191bmlmJGAxMiBtZXRyb3NgJENvc3Nlbm8sCmN1dGlhX2VzZWNfdGVycmFfbWVpb191bmlmJGAxMiBtZXRyb3NgJGBQb2xpbm9taWFsIHNpbXBsZXNgCikKYGBgCgojIyMgQ3V0aWFzIGRhIFBhcm5hIGRhIFNlcnJhIGRvIFBhcmRvIHBhcmEgZGlmZXJlbnRlcyBkaXN0w6JuY2lhcyBkZSB0cnVuY2FtZW50bwoKYGBge3J9CmN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvIDwtIHRyYW5zZm9ybWFyX3BhcmFfZGlzdGFuY2VSX2NvdmFyaWF2ZWlzKCkgfD4gCiAgZmlsdGVyKAogICAgUmVnaW9uLkxhYmVsID09ICJQYXJuYSBkYSBTZXJyYSBkbyBQYXJkbyIsCiAgICBzcF9uYW1lID09ICJEYXN5cHJvY3RhIGNyb2Nvbm90YSIKICApIHw+IAogIGRyb3BfbmEoZGlzdGFuY2UpCiAgCmBgYAoKYGBge3J9CiMgZGVzZW5oYSBvIGdyYWZpY28gY29tIGEgZGlzdHJpYnVpY2FvIGRlIGRpc3RhbmNpYXMgcGVycGVuZGljdWxhcmVzCmN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvIHw+IAogIGZpbHRlcihkaXN0YW5jZSA8IDE1LAogICAgICAgICBkaXN0YW5jZSA+IDApIHw+IAogIHBsb3Rhcl9kaXN0cmlidWljYW9fZGlzdGFuY2lhX2ludGVyYXRpdm8oKQpgYGAKCiMjIyMgKkhhbGYtTm9ybWFsKiBzZW0gdGVybW9zIGRlIGFqdXN0ZSBlIGNvbSB0ZXJtb3MgZGUgYWp1c3RlIENvc3Nlbm8gZSBQb2xpbm9taWFsIGRlIEhlcm1pdGUKCkFqdXN0YW5kbyB1bSBtb2RlbG8gYW8gZGFkb3MgZGFzIGN1dGlhcyAqRGFzeXByb2N0YSBjcm9jb25vdGEqLCBjb25maWd1cmFuZG8gdW1hIGRpc3TDom5jaWEgbGltaXRlIGRlIDIwbSBlIHVzYW5kbyAqSGFsZi1ub3JtYWwqIGNvbW8gKmtleSBmdW5jdGlvbiogdXNhbmRvIG8gYXJndW1lbnRvIGBrZXlgLCBzZW0gdGVybW8gZGUgYWp1c3RlLgoKYGBge3J9CiMgYWp1c3RhbmRvIGEgZnVuw6fDo28gZGUgZGV0ZWPDp8OjbyBwYXJhIHVtYSBkaXN0YW5jaWEgZGUgdHJ1bmNhbWVudG8gZGUgMjAsIDE1LCAxMCBlIDUgbWV0cm9zCiMgZHNpdGFuY2lhcyBkZSB0cnVuY2FtZW50bwpkaXN0X3RydW5jYW1lbnRvIDwtIGxpc3QoCiAgYDIwIG1ldHJvc2AgPSAyMCwgCiAgYDE1IG1ldHJvc2AgPSAxNSwgCiAgYDEwIG1ldHJvc2AgPSAxMCwKICBgNSBtZXRyb3NgID0gNQopCgojIEtleSBmdW5jdGlvbiAtIEhhbGYtbm9ybWFsIApjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb19obiA8LSBwdXJycjo6bWFwKAogIGRpc3RfdHJ1bmNhbWVudG8sCiAgXCgueCkgYWp1c3RlX21vZGVsb3NfZGlzdGFuY2VfaG4oCiAgICBjdXRpYV9wYXJuYV9zZXJyYV9wYXJkbywgCiAgICB0cnVuY2FtZW50byA9IC54CiAgKQogICkKYGBgCgpgYGB7cn0KY3V0aWFfcGFybmFfc2VycmFfcGFyZG9faG4KYGBgCgojIyMjICpIYXphcmQtUmF0ZSogc2VtIHRlcm1vcyBkZSBhanVzdGUgZSBjb20gdGVybW9zIGRlIGFqdXN0ZSBDb3NzZW5vIGUgUG9saW5vbWlhbCBkZSBIZXJtaXRlCgpBanVzdGFuZG8gdW0gbW9kZWxvIGFvIGRhZG9zIGRhIGN1dGlhICpEYXN5cHJvY3RhIGNyb2Nvbm90YSosIGNvbmZpZ3VyYW5kbyB1bWEgZGlzdMOibmNpYSBsaW1pdGUgZGUgMjBtIGUgdXNhbmRvICpIYXphcmQgcmF0ZSogY29tbyAqa2V5IGZ1bmN0aW9uKiB1c2FuZG8gbyBhcmd1bWVudG8gYGtleWAuCgpgYGB7cn0KIyBhanVzdGFuZG8gYSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvIHBhcmEgdW1hIGRpc3RhbmNpYSBkZSB0cnVuY2FtZW50byBkZSAyMCwgMTUsIDEwIGUgNSBtZXRyb3MKIyBLZXkgZnVuY3Rpb24gLSBIYXphcmQtcmF0ZQpjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb19ociA8LSBwdXJycjo6bWFwKAogIGRpc3RfdHJ1bmNhbWVudG8sCiAgXCgueCkgYWp1c3RlX21vZGVsb3NfZGlzdGFuY2VfaHIoCiAgICBjdXRpYV9wYXJuYV9zZXJyYV9wYXJkbywgCiAgICB0cnVuY2FtZW50byA9IC54CiAgKQogICkKYGBgCgojIyMjICpVbmlmb3JtKiBzZW0gdGVybW9zIGRlIGFqdXN0ZSBlIGNvbSB0ZXJtb3MgZGUgYWp1c3RlIENvc3Nlbm8gZSBQb2xpbm9taWFsIGRlIEhlcm1pdGUKCkFqdXN0YW5kbyB1bSBtb2RlbG8gYW8gZGFkb3MgZGFzIGN1dGlhcyAqRGFzeXByb2N0YSBjcm9jb25vdGEqLCBjb25maWd1cmFuZG8gdW1hIGRpc3TDom5jaWEgbGltaXRlIGRlIDIwbSBlIHVzYW5kbyAqVW5pZm9ybSogY29tbyAqa2V5IGZ1bmN0aW9uKiB1c2FuZG8gbyBhcmd1bWVudG8gYGtleWAsIHNlbSB0ZXJtbyBkZSBhanVzdGUuCgpgYGB7cn0KIyBhanVzdGFuZG8gYSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvIHBhcmEgdW1hIGRpc3RhbmNpYSBkZSB0cnVuY2FtZW50byBkZSAyMCwgMTUsIDEwIGUgNSBtZXRyb3MKIyBLZXkgZnVuY3Rpb24gLSBVbmlmb3JtCmN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvX3VuaWYgPC0gcHVycnI6Om1hcCgKICBkaXN0X3RydW5jYW1lbnRvLAogIFwoLngpIGFqdXN0ZV9tb2RlbG9zX2Rpc3RhbmNlX3VuaWYoCiAgICBjdXRpYV9wYXJuYV9zZXJyYV9wYXJkbywgCiAgICB0cnVuY2FtZW50byA9IC54CiAgKQopCmBgYAoKIyMjIyMjIFNlbGXDp8OjbyBkZSBtb2RlbG9zCgpgYGB7cn0Kc3VtbWFyaXplX2RzX21vZGVscygKICBjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb19obiRgMjAgbWV0cm9zYCRgU2VtIHRlcm1vYCwKY3V0aWFfcGFybmFfc2VycmFfcGFyZG9faG4kYDIwIG1ldHJvc2AkQ29zc2VubywKICBjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb19obiRgMjAgbWV0cm9zYCRgSGVybWl0ZSBwb2xpbm9taWFsYCwKY3V0aWFfcGFybmFfc2VycmFfcGFyZG9faHIkYDIwIG1ldHJvc2AkYFNlbSB0ZXJtb2AsCmN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvX2hyJGAyMCBtZXRyb3NgJENvc3Nlbm8sCmN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvX2hyJGAyMCBtZXRyb3NgJGBQb2xpbm9taWFsIHNpbXBsZXNgLApjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb191bmlmJGAyMCBtZXRyb3NgJENvc3Nlbm8sCmN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvX3VuaWYkYDIwIG1ldHJvc2AkYFBvbGlub21pYWwgc2ltcGxlc2AKKQpgYGAKCmBgYHtyfQpzdW1tYXJpemVfZHNfbW9kZWxzKAogIGN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvX2huJGAxNSBtZXRyb3NgJGBTZW0gdGVybW9gLApjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb19obiRgMTUgbWV0cm9zYCRDb3NzZW5vLAogIGN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvX2huJGAxNSBtZXRyb3NgJGBIZXJtaXRlIHBvbGlub21pYWxgLApjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb19ociRgMTUgbWV0cm9zYCRgU2VtIHRlcm1vYCwKY3V0aWFfcGFybmFfc2VycmFfcGFyZG9faHIkYDE1IG1ldHJvc2AkQ29zc2VubywKY3V0aWFfcGFybmFfc2VycmFfcGFyZG9faHIkYDE1IG1ldHJvc2AkYFBvbGlub21pYWwgc2ltcGxlc2AsCmN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvX3VuaWYkYDE1IG1ldHJvc2AkQ29zc2VubywKY3V0aWFfcGFybmFfc2VycmFfcGFyZG9fdW5pZiRgMTUgbWV0cm9zYCRgUG9saW5vbWlhbCBzaW1wbGVzYAopCmBgYAoKYGBge3J9CnN1bW1hcml6ZV9kc19tb2RlbHMoCiAgY3V0aWFfcGFybmFfc2VycmFfcGFyZG9faG4kYDEwIG1ldHJvc2AkYFNlbSB0ZXJtb2AsCmN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvX2huJGAxMCBtZXRyb3NgJENvc3Nlbm8sCiAgY3V0aWFfcGFybmFfc2VycmFfcGFyZG9faG4kYDEwIG1ldHJvc2AkYEhlcm1pdGUgcG9saW5vbWlhbGAsCmN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvX2hyJGAxMCBtZXRyb3NgJGBTZW0gdGVybW9gLApjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb19ociRgMTAgbWV0cm9zYCRDb3NzZW5vLApjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb19ociRgMTAgbWV0cm9zYCRgUG9saW5vbWlhbCBzaW1wbGVzYCwKY3V0aWFfcGFybmFfc2VycmFfcGFyZG9fdW5pZiRgMTAgbWV0cm9zYCRgU2VtIHRlcm1vYCwKY3V0aWFfcGFybmFfc2VycmFfcGFyZG9fdW5pZiRgMTAgbWV0cm9zYCRDb3NzZW5vLApjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb191bmlmJGAxMCBtZXRyb3NgJGBQb2xpbm9taWFsIHNpbXBsZXNgCikKYGBgCgpgYGB7cn0Kc3VtbWFyaXplX2RzX21vZGVscygKICBjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb19obiRgNSBtZXRyb3NgJGBTZW0gdGVybW9gLApjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb19obiRgNSBtZXRyb3NgJENvc3Nlbm8sCiAgY3V0aWFfcGFybmFfc2VycmFfcGFyZG9faG4kYDUgbWV0cm9zYCRgSGVybWl0ZSBwb2xpbm9taWFsYCwKY3V0aWFfcGFybmFfc2VycmFfcGFyZG9faHIkYDUgbWV0cm9zYCRgU2VtIHRlcm1vYCwKY3V0aWFfcGFybmFfc2VycmFfcGFyZG9faHIkYDUgbWV0cm9zYCRDb3NzZW5vLApjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb19ociRgNSBtZXRyb3NgJGBQb2xpbm9taWFsIHNpbXBsZXNgLApjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb191bmlmJGA1IG1ldHJvc2AkYFNlbSB0ZXJtb2AsCmN1dGlhX3Bhcm5hX3NlcnJhX3BhcmRvX3VuaWYkYDUgbWV0cm9zYCRDb3NzZW5vLApjdXRpYV9wYXJuYV9zZXJyYV9wYXJkb191bmlmJGA1IG1ldHJvc2AkYFBvbGlub21pYWwgc2ltcGxlc2AKKQpgYGAKCiMjIyMjIFRlbnRhdGl2YSBkZSBmYXplciBhIHNlbGXDp8OjIG9kZSBtb2RlbG9zIHVzYW5kbyBwdXJyciAtIHRlbnRhciBhbmluaGFyIG1haXMgdW0gbWFwCgpgYGB7cn0KcHVycnI6Om1hcF9kZigKICBsaXN0KAogICAgY3V0aWFfZXNlY190ZXJyYV9tZWlvX2huJGAyMCBtZXRyb3NgLAogICAgY3V0aWFfZXNlY190ZXJyYV9tZWlvX2hyJGAyMCBtZXRyb3NgCiAgKSwKICBcKC54KSBwdXJycjo6bWFwX2RmKC54LCBcKC55KSBzdW1tYXJpemVfZHNfbW9kZWxzKC55KSkKKQoKcHVycnI6Om1hcF9kZigKICBjdXRpYV9lc2VjX3RlcnJhX21laW9faG4kYDE1IG1ldHJvc2AsCiAgXCgueCkgc3VtbWFyaXplX2RzX21vZGVscygueCkKKQoKcHVycnI6Om1hcF9kZigKICBjdXRpYV9lc2VjX3RlcnJhX21laW9faG4kYDEwIG1ldHJvc2AsCiAgXCgueCkgc3VtbWFyaXplX2RzX21vZGVscygueCkKKQoKcHVycnI6Om1hcF9kZigKICBjdXRpYV9lc2VjX3RlcnJhX21laW9faG4kYDUgbWV0cm9zYCwKICBcKC54KSBzdW1tYXJpemVfZHNfbW9kZWxzKC54KQopCmBgYAoKCgpgYGB7cn0KCmBgYAoKIyBTdWdlc3TDtWVzIGNoYXQgR1BUCgojIyBQZXJndW50YSAxIC0gRmFsdGEgZGUgbW9ub3RvbmljaWRhZGUgbmEgZnVuw6fDo28gZGUgZGV0ZWPDp8OjbwoKRXN0b3UgYWp1c3RhbmRvIG1vZGVsb3MgZGUgYW1vc3RyYWdlbSBwb3IgZGlzdMOibmNpYSBwYXJhIG9idGVyIGVzdGltYXRpdmEgZGUgZGVuc2lkYWRlIGRlIG9iamV0b3MgdXRpbGl6YW5kbyBvIHBhY290ZSBEaXN0YW5jZSBubyBhbWJpZW50ZSBkZSBwcm9ncmFtYcOnw6NvIFIuIEFsZ3VucyBkb3MgbW9kZWxvcyBhb3MgZGFkb3MgZXN0w6NvIGFwcmVzZW50YW5kbyBwcm9ibGVtYXMgZGUgZmFsdGEgZGUgbW9ub3RvbmljaWRhZGUgbmEgZnVuw6fDo28gZGUgZGV0ZWPDp8Ojby4gVGVtIGFsZ3VtYSBzdWdlc3TDo28gZGUgY29tbyBwb3NzbyByZXNvbHZlciBvIHByb2JsZW1hIGRlIGZhbHRhIGRlIG1vbm90b25pY2lkYWRlIG5hIGZ1bsOnw6NvIGRlIGRldGVjw6fDo28/CgpSZXNwb3N0YTogQSBmYWx0YSBkZSBtb25vdG9uaWNpZGFkZSBuYSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvIGVtIG1vZGVsb3MgZGUgYW1vc3RyYWdlbSBwb3IgZGlzdMOibmNpYSBwb2RlIHNlciB1bSBkZXNhZmlvLCBtYXMgZXhpc3RlbSBhbGd1bWFzIGFib3JkYWdlbnMgcXVlIHZvY8OqIHBvZGUgdGVudGFyIHBhcmEgcmVzb2x2ZXIgZXNzZSBwcm9ibGVtYS4gQXF1aSBlc3TDo28gYWxndW1hcyBzdWdlc3TDtWVzOgoKMS4gVmVyaWZpcXVlIG9zIGRhZG9zOiBQcmltZWlybywgdmVyaWZpcXVlIHNlIG9zIHNldXMgZGFkb3MgZXN0w6NvIGNvcnJldG9zIGUgc2UgbsOjbyBow6EgZXJyb3MgbmEgc3VhIHByZXBhcmHDp8OjbyBvdSBwcm9jZXNzYW1lbnRvLiBFcnJvcyBub3MgZGFkb3MgcG9kZW0gbGV2YXIgYSByZXN1bHRhZG9zIG7Do28gZXNwZXJhZG9zIGUgw6AgZmFsdGEgZGUgbW9ub3RvbmljaWRhZGUgbmEgZnVuw6fDo28gZGUgZGV0ZWPDp8Ojby4KCjIuIEFqdXN0ZSBkZSBwYXLDom1ldHJvczogRXhwZXJpbWVudGUgYWp1c3RhciBvcyBwYXLDom1ldHJvcyBkbyBtb2RlbG8gZGUgYW1vc3RyYWdlbSBwb3IgZGlzdMOibmNpYS4gUG9yIGV4ZW1wbG8sIHZvY8OqIHBvZGUgYWx0ZXJhciBvIHZhbG9yIGRvIHJhaW8gZGUgYnVzY2EgKHNlYXJjaCByYWRpdXMpIG91IGRvIG7Dum1lcm8gbcOtbmltbyBkZSB2aXppbmhvcyBuZWNlc3PDoXJpb3MgcGFyYSBkZXRlY8Onw6NvLiBQZXF1ZW5hcyBhbHRlcmHDp8O1ZXMgbmVzc2VzIHBhcsOibWV0cm9zIHBvZGVtIHRlciB1bSBpbXBhY3RvIHNpZ25pZmljYXRpdm8gbmEgbW9ub3RvbmljaWRhZGUgZGEgZnVuw6fDo28gZGUgZGV0ZWPDp8Ojby4KCjMuIFRyYW5zZm9ybWHDp8O1ZXMgZG9zIGRhZG9zOiBDb25zaWRlcmUgYXBsaWNhciB0cmFuc2Zvcm1hw6fDtWVzIG5vcyBzZXVzIGRhZG9zIGFudGVzIGRlIGFqdXN0YXIgbyBtb2RlbG8uIFBvciBleGVtcGxvLCB2b2PDqiBwb2RlIHRlbnRhciBhcGxpY2FyIHVtYSB0cmFuc2Zvcm1hw6fDo28gbG9nYXLDrXRtaWNhIG91IHVtYSB0cmFuc2Zvcm1hw6fDo28gQm94LUNveCBwYXJhIHJlZHV6aXIgYSBlc2NhbGEgZG9zIGRhZG9zIGUgdG9ybsOhLWxvcyBtYWlzIGFkZXF1YWRvcyBwYXJhIG8gbW9kZWxvIGRlIGFtb3N0cmFnZW0gcG9yIGRpc3TDom5jaWEuCgo0LiBTdWF2aXphw6fDo286IFNlIHZvY8OqIGlkZW50aWZpY2FyIHJlZ2nDtWVzIGNvbSBmYWx0YSBkZSBtb25vdG9uaWNpZGFkZSBuYSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvLCBwb2RlIHNlciDDunRpbCBhcGxpY2FyIHTDqWNuaWNhcyBkZSBzdWF2aXphw6fDo28uIFBvciBleGVtcGxvLCB2b2PDqiBwb2RlIHV0aWxpemFyIHTDqWNuaWNhcyBkZSBzdWF2aXphw6fDo28gbG9jYWwsIGNvbW8gbyBrZXJuZWwgc21vb3RoaW5nLCBwYXJhIHRvcm5hciBhIGZ1bsOnw6NvIGRlIGRldGVjw6fDo28gbWFpcyBzdWF2ZSBlIG1vbm90w7RuaWNhLgoKNS4gT3V0cm9zIG1vZGVsb3Mgb3UgbcOpdG9kb3M6IFNlIG9zIG1vZGVsb3MgZGUgYW1vc3RyYWdlbSBwb3IgZGlzdMOibmNpYSBjb250aW51YXJlbSBhIGFwcmVzZW50YXIgcHJvYmxlbWFzIGRlIGZhbHRhIGRlIG1vbm90b25pY2lkYWRlLCB0YWx2ZXogc2VqYSBuZWNlc3PDoXJpbyBleHBsb3JhciBvdXRyb3MgbW9kZWxvcyBvdSBtw6l0b2RvcyBkZSBlc3RpbWF0aXZhIGRlIGRlbnNpZGFkZS4gRXhpc3RlbSBkaXZlcnNhcyBhYm9yZGFnZW5zIGRpc3BvbsOtdmVpcyBuYSBsaXRlcmF0dXJhLCBjb21vIG1vZGVsb3MgYmFzZWFkb3MgZW0ga3JpZ2FnZW0gb3UgbcOpdG9kb3MgZGUgZXN0aW1hdGl2YSBkZSBkZW5zaWRhZGUga2VybmVsLgoKNi4gVmFsaWRhw6fDo28gY3J1emFkYTogUmVhbGl6ZSB1bWEgdmFsaWRhw6fDo28gY3J1emFkYSBkbyBzZXUgbW9kZWxvIHBhcmEgYXZhbGlhciBzdWEgY2FwYWNpZGFkZSBkZSBnZW5lcmFsaXphw6fDo28uIMOAcyB2ZXplcywgYSBmYWx0YSBkZSBtb25vdG9uaWNpZGFkZSBwb2RlIHNlciBjYXVzYWRhIHBvciBvdmVyZml0dGluZyBub3MgZGFkb3MgZGUgdHJlaW5hbWVudG8uIEEgdmFsaWRhw6fDo28gY3J1emFkYSBwb2RlIGFqdWRhciBhIGlkZW50aWZpY2FyIGVzc2UgcHJvYmxlbWEgZSBvcmllbnRhciBhanVzdGVzIGFkaWNpb25haXMgbm8gbW9kZWxvLgoKTGVtYnJlLXNlIGRlIHF1ZSBhIGZhbHRhIGRlIG1vbm90b25pY2lkYWRlIG5hIGZ1bsOnw6NvIGRlIGRldGVjw6fDo28gcG9kZSBpbmRpY2FyIHVtYSBpbmFkZXF1YcOnw6NvIGRvIG1vZGVsbyBlbSByZWxhw6fDo28gYW9zIHNldXMgZGFkb3Mgb3UgY2FyYWN0ZXLDrXN0aWNhcyBlc3BlY8OtZmljYXMgZG8gcHJvYmxlbWEgZW0gcXVlc3TDo28uIFBvcnRhbnRvLCBwb2RlIHNlciBuZWNlc3PDoXJpbyBleHBsb3JhciBkaWZlcmVudGVzIGFib3JkYWdlbnMgZSB0w6ljbmljYXMgcGFyYSBvYnRlciByZXN1bHRhZG9zIHNhdGlzZmF0w7NyaW9zLgoKIyMgUGVyZ3VudGEgMjogRmFsdGEgZGUgY29udmVyZ8OqbmNpYQoKQSBmYWx0YSBkZSBjb252ZXJnw6puY2lhIGVtIG1vZGVsb3MgZGUgYW1vc3RyYWdlbSBwb3IgZGlzdMOibmNpYSBwb2RlIHNlciB1bSBkZXNhZmlvLCBtYXMgZXhpc3RlbSBhbGd1bWFzIHN1Z2VzdMO1ZXMgcXVlIHZvY8OqIHBvZGUgc2VndWlyIHBhcmEgdGVudGFyIHJlc29sdmVyIGVzc2UgcHJvYmxlbWEuIEFxdWkgZXN0w6NvIGFsZ3VtYXMgb3DDp8O1ZXM6CgoxLiBWZXJpZmlxdWUgb3MgZGFkb3M6IFZlcmlmaXF1ZSBzZSBvcyBzZXVzIGRhZG9zIGVzdMOjbyBjb3JyZXRvcyBlIHNlIG7Do28gaMOhIGVycm9zIG5hIHByZXBhcmHDp8OjbyBvdSBwcm9jZXNzYW1lbnRvIGRvcyBtZXNtb3MuIEVycm9zIG5vcyBkYWRvcyBwb2RlbSBsZXZhciBhIHByb2JsZW1hcyBkZSBjb252ZXJnw6puY2lhLiBWZXJpZmlxdWUgdGFtYsOpbSBzZSBuw6NvIGjDoSB2YWxvcmVzIGV4dHJlbW9zIG91IGRhZG9zIGF1c2VudGVzIHF1ZSBwb3NzYW0gZXN0YXIgYWZldGFuZG8gbyBhanVzdGUgZG8gbW9kZWxvLgoKMi4gUmVkdXphIGEgY29tcGxleGlkYWRlIGRvIG1vZGVsbzogU2UgbyBzZXUgbW9kZWxvIGF0dWFsIMOpIG11aXRvIGNvbXBsZXhvLCBwb2RlIHNlciBkaWbDrWNpbCBvYnRlciBhIGNvbnZlcmfDqm5jaWEuIENvbnNpZGVyZSByZWR1emlyIGEgY29tcGxleGlkYWRlIGRvIG1vZGVsbywgZGltaW51aW5kbyBvIG7Dum1lcm8gZGUgcGFyw6JtZXRyb3MgYSBzZXJlbSBlc3RpbWFkb3Mgb3Ugc2ltcGxpZmljYW5kbyBhIGVzdHJ1dHVyYSBkbyBtb2RlbG8uCgozLiBJbmljaWFsaXphw6fDo28gYWRlcXVhZGE6IFRlbnRlIGZvcm5lY2VyIHVtYSBib2EgaW5pY2lhbGl6YcOnw6NvIHBhcmEgb3MgcGFyw6JtZXRyb3MgZG8gbW9kZWxvLiBJc3NvIHBvZGUgYWp1ZGFyIGEgZXZpdGFyIHByb2JsZW1hcyBkZSBjb252ZXJnw6puY2lhLiBTZSBwb3Nzw612ZWwsIHV0aWxpemUgdmFsb3JlcyBpbmljaWFpcyBwcsOzeGltb3MgZG9zIHZhbG9yZXMgdmVyZGFkZWlyb3MgZG9zIHBhcsOibWV0cm9zIG91IHV0aWxpemUgcmVzdWx0YWRvcyBkZSBtb2RlbG9zIGFudGVyaW9yZXMgY29tbyBwb250byBkZSBwYXJ0aWRhLgoKNC4gQWp1c3RlIGRvcyBwYXLDom1ldHJvcyBkbyBhbGdvcml0bW8gZGUgb3RpbWl6YcOnw6NvOiBNdWl0YXMgdmV6ZXMsIG8gcHJvYmxlbWEgZGUgZmFsdGEgZGUgY29udmVyZ8OqbmNpYSBlc3TDoSByZWxhY2lvbmFkbyBhb3MgcGFyw6JtZXRyb3MgZG8gYWxnb3JpdG1vIGRlIG90aW1pemHDp8OjbyB1dGlsaXphZG8gcGFyYSBhanVzdGFyIG8gbW9kZWxvLiBFeHBlcmltZW50ZSBhanVzdGFyIGVzc2VzIHBhcsOibWV0cm9zLCBjb21vIG8gdGFtYW5obyBkbyBwYXNzbyAoc3RlcCBzaXplKSwgYSB0b2xlcsOibmNpYSBkZSBjb252ZXJnw6puY2lhIChjb252ZXJnZW5jZSB0b2xlcmFuY2UpIG91IG8gbsO6bWVybyBtw6F4aW1vIGRlIGl0ZXJhw6fDtWVzIHBlcm1pdGlkYXMuIFRlbnRlIGRpZmVyZW50ZXMgY29tYmluYcOnw7VlcyBkZSB2YWxvcmVzIHBhcmEgZXNzZXMgcGFyw6JtZXRyb3MgZSBvYnNlcnZlIHNlIGlzc28gYWp1ZGEgYSBhbGNhbsOnYXIgYSBjb252ZXJnw6puY2lhLgoKNS4gTm9ybWFsaXphw6fDo28gZG9zIGRhZG9zOiBDb25zaWRlcmUgbm9ybWFsaXphciBvcyBzZXVzIGRhZG9zIGFudGVzIGRlIGFqdXN0YXIgbyBtb2RlbG8uIElzc28gcG9kZSBhanVkYXIgYSBldml0YXIgcHJvYmxlbWFzIG51bcOpcmljb3Mgb3UgZGUgZXNjYWxhIHF1ZSBwb3NzYW0gYWZldGFyIGEgY29udmVyZ8OqbmNpYS4gTm9ybWFsaXphciBvcyBkYWRvcyBwYXJhIHVtYSBlc2NhbGEgY29tIG3DqWRpYSB6ZXJvIGUgZGVzdmlvIHBhZHLDo28gaWd1YWwgYSB1bSDDqSB1bWEgYWJvcmRhZ2VtIGNvbXVtLgoKNi4gRXhwbG9yYXIgb3V0cm9zIGFsZ29yaXRtb3Mgb3UgbcOpdG9kb3M6IFNlIG8gbW9kZWxvIGRlIGFtb3N0cmFnZW0gcG9yIGRpc3TDom5jaWEgY29udGludWFyIGFwcmVzZW50YW5kbyBwcm9ibGVtYXMgZGUgY29udmVyZ8OqbmNpYSwgdm9jw6ogcG9kZSBjb25zaWRlcmFyIGV4cGxvcmFyIG91dHJvcyBhbGdvcml0bW9zIG91IG3DqXRvZG9zIHBhcmEgZXN0aW1hdGl2YSBkZSBkZW5zaWRhZGUuIEV4aXN0ZW0gZGlmZXJlbnRlcyBhYm9yZGFnZW5zIGRpc3BvbsOtdmVpcyBuYSBsaXRlcmF0dXJhLCBjb21vIG3DqXRvZG9zIGJhc2VhZG9zIGVtIE3DoXhpbWEgVmVyb3NzaW1pbGhhbsOnYSAoTWF4aW11bSBMaWtlbGlob29kKSBvdSBhbGdvcml0bW9zIGRlIE1vbnRlIENhcmxvLgoKNy4gVmVyaWZpcXVlIGEgZG9jdW1lbnRhw6fDo28gZSByZWN1cnNvcyBkbyBwYWNvdGU6IFZlcmlmaXF1ZSBhIGRvY3VtZW50YcOnw6NvIGRvIHBhY290ZSBEaXN0YW5jZSBlIG9zIHJlY3Vyc29zIGRpc3BvbsOtdmVpcyBwYXJhIGVuY29udHJhciBpbmZvcm1hw6fDtWVzIGVzcGVjw61maWNhcyBzb2JyZSBvcyBwcm9ibGVtYXMgZGUgY29udmVyZ8OqbmNpYSBlIHBvc3PDrXZlaXMgc29sdcOnw7Vlcy4gRsOzcnVucyBkZSBkaXNjdXNzw6NvIG91IGdydXBvcyBkZSB1c3XDoXJpb3MgcmVsYWNpb25hZG9zIGFvIHBhY290ZSB0YW1iw6ltIHBvZGVtIHNlciDDunRlaXMgcGFyYSBvYnRlciBzdXBvcnRlIGUgb3JpZW50YcOnw6NvLgoKTGVtYnJlLXNlIGRlIHF1ZSBhIGZhbHRhIGRlIGNvbnZlcmfDqm5jaWEgcG9kZSB0ZXIgdsOhcmlhcyBjYXVzYXMgZSBuw6NvIGjDoSB1bWEgc29sdcOnw6NvIMO6bmljYSBwYXJhIHRvZG9zIG9zIGNhc29zLiDDiSBpbXBvcnRhbnRlIGl0ZXJhciBlIGV4cGVyaW1lbnRhciBkaWZlcmVudGVzIGFib3JkYWdlbnMgYXTDqSBlbmNvbnRyYXIgdW1hIHNvbHXDp8OjbyBhZGVxdWFkYSBwYXJhIG8gc2V1IHByb2JsZW1hIGVzcGVjw61maWNvLgoKIyMgUGVyZ3VudGEgMzogUGljbyBwcsOzeGltbyBkYSBkaXN0w6JuY2lhIHplcm8KClBpY29zIHByw7N4aW1vcyBhIGRpc3TDom5jaWEgemVybyBwb2RlbSBzZXIgdW0gZGVzYWZpbyBhbyBhanVzdGFyIG1vZGVsb3MgZGUgYW1vc3RyYWdlbSBwb3IgZGlzdMOibmNpYS4gRXNzZXMgcGljb3MgcG9kZW0gaW5kaWNhciBhIHByZXNlbsOnYSBkZSBwb250b3MgbXVpdG8gcHLDs3hpbW9zIHVucyBkb3Mgb3V0cm9zLCBvIHF1ZSBwb2RlIGltcGFjdGFyIG5lZ2F0aXZhbWVudGUgYSBlc3RpbWF0aXZhIGRlIGRlbnNpZGFkZS4gQXF1aSBlc3TDo28gYWxndW1hcyBzdWdlc3TDtWVzIHBhcmEgbGlkYXIgY29tIGVzc2UgcHJvYmxlbWE6CgoxLiBWZXJpZmlxdWUgYSBxdWFsaWRhZGUgZG9zIGRhZG9zOiBWZXJpZmlxdWUgc2Ugb3Mgc2V1cyBkYWRvcyBlc3TDo28gY29ycmV0b3MgZSBzZSBuw6NvIGjDoSBlcnJvcyBuYSBwcmVwYXJhw6fDo28gb3UgcHJvY2Vzc2FtZW50byBkb3MgbWVzbW9zLiBFcnJvcyBub3MgZGFkb3MgcG9kZW0gbGV2YXIgYSBwaWNvcyBwcsOzeGltb3MgYSBkaXN0w6JuY2lhIHplcm8uIFZlcmlmaXF1ZSB0YW1iw6ltIHNlIG7Do28gaMOhIHBvbnRvcyBkdXBsaWNhZG9zIG91IGRhZG9zIGF1c2VudGVzIHF1ZSBwb3NzYW0gZXN0YXIgY2F1c2FuZG8gZXNzZXMgcGljb3MuCgoyLiBMaW1wZXphIGRvcyBkYWRvczogQ29uc2lkZXJlIGEgcG9zc2liaWxpZGFkZSBkZSByZW1vdmVyIG91IGFqdXN0YXIgcG9udG9zIHByw7N4aW1vcyBkZW1haXMgdW5zIGRvcyBvdXRyb3MuIFZvY8OqIHBvZGUgZGVmaW5pciB1bSBsaW1pYXIgZGUgZGlzdMOibmNpYSBtw61uaW1hIGFiYWl4byBkbyBxdWFsIG9zIHBvbnRvcyBzZXLDo28gY29uc2lkZXJhZG9zIGR1cGxpY2Fkb3Mgb3UgZnVuZGlkb3MgZW0gdW0gw7puaWNvIHBvbnRvLiBJc3NvIHBvZGUgYWp1ZGFyIGEgZXZpdGFyIG9zIHBpY29zIHByw7N4aW1vcyBhIGRpc3TDom5jaWEgemVyby4KCjMuIFRyYW5zZm9ybWHDp8OjbyBkb3MgZGFkb3M6IENvbnNpZGVyZSBhcGxpY2FyIHVtYSB0cmFuc2Zvcm1hw6fDo28gbm9zIGRhZG9zIGFudGVzIGRlIGFqdXN0YXIgbyBtb2RlbG8uIFBvciBleGVtcGxvLCB2b2PDqiBwb2RlIHRlbnRhciBhcGxpY2FyIHVtYSB0cmFuc2Zvcm1hw6fDo28gbG9nYXLDrXRtaWNhIG91IHVtYSB0cmFuc2Zvcm1hw6fDo28gQm94LUNveCBwYXJhIHJlZHV6aXIgYSBlc2NhbGEgZG9zIGRhZG9zIGUgc3Vhdml6YXIgb3MgcGljb3MgcHLDs3hpbW9zIGEgZGlzdMOibmNpYSB6ZXJvLgoKNC4gVXRpbGl6ZSB1bSByYWlvIGRlIGJ1c2NhIG1haW9yOiBFeHBlcmltZW50ZSBhdW1lbnRhciBvIHJhaW8gZGUgYnVzY2EgKHNlYXJjaCByYWRpdXMpIHV0aWxpemFkbyBubyBtb2RlbG8gZGUgYW1vc3RyYWdlbSBwb3IgZGlzdMOibmNpYS4gSXNzbyBwb2RlIGFqdWRhciBhIGNhcHR1cmFyIGluZm9ybWHDp8O1ZXMgc29icmUgYSBkZW5zaWRhZGUgZW0gdW1hIHJlZ2nDo28gbWFpcyBhbXBsYSBhbyByZWRvciBkZSBjYWRhIHBvbnRvIGUgcmVkdXppciBhIGluZmx1w6puY2lhIGRvcyBwaWNvcyBwcsOzeGltb3MgYSBkaXN0w6JuY2lhIHplcm8uCgo1LiBDb25zaWRlcmUgb3V0cm9zIG1vZGVsb3Mgb3UgbcOpdG9kb3M6IFNlIG9zIHBpY29zIHByw7N4aW1vcyBhIGRpc3TDom5jaWEgemVybyBjb250aW51YXJlbSBhIHNlciB1bSBwcm9ibGVtYSwgdm9jw6ogcG9kZSBleHBsb3JhciBvdXRyb3MgbW9kZWxvcyBvdSBtw6l0b2RvcyBkZSBlc3RpbWF0aXZhIGRlIGRlbnNpZGFkZSBxdWUgc2VqYW0gbWFpcyByb2J1c3RvcyBhIGVzc2UgdGlwbyBkZSBzaXR1YcOnw6NvLiBQb3IgZXhlbXBsbywgbW9kZWxvcyBiYXNlYWRvcyBlbSBrZXJuZWwgcG9kZW0gc2VyIHVtYSBhbHRlcm5hdGl2YSB2acOhdmVsLCBwb2lzIHBlcm1pdGVtIHVtYSBzdWF2aXphw6fDo28gbWFpcyBmbGV4w612ZWwgZSBwb2RlbSBsaWRhciBtZWxob3IgY29tIGEgcHJlc2Vuw6dhIGRlIHBpY29zIHByw7N4aW1vcy4KCjYuIEV4cGVyaW1lbnRlIGRpZmVyZW50ZXMgY29uZmlndXJhw6fDtWVzOiBGYcOnYSBleHBlcmltZW50b3MgY29tIGRpZmVyZW50ZXMgY29uZmlndXJhw6fDtWVzIGUgcGFyw6JtZXRyb3MgZG8gbW9kZWxvIGRlIGFtb3N0cmFnZW0gcG9yIGRpc3TDom5jaWEuIElzc28gaW5jbHVpIGEgZXNjb2xoYSBkbyB0aXBvIGRlIGZ1bsOnw6NvIGRlIGRldGVjw6fDo28gZSBhIGRlZmluacOnw6NvIGRlIHBhcsOibWV0cm9zIHJlbGFjaW9uYWRvcyDDoCBkZXRlY8Onw6NvIGUgYW8gc3Vhdml6YcOnw6NvIGRvcyBwaWNvcyBwcsOzeGltb3MgYSBkaXN0w6JuY2lhIHplcm8uCgpMZW1icmUtc2UgZGUgcXVlIGEgc29sdcOnw6NvIGlkZWFsIGRlcGVuZGVyw6EgZGFzIGNhcmFjdGVyw61zdGljYXMgZXNwZWPDrWZpY2FzIGRvcyBzZXVzIGRhZG9zIGUgZG8gcHJvYmxlbWEgZW0gcXVlc3TDo28uIMOJIGltcG9ydGFudGUgaXRlcmFyLCBleHBlcmltZW50YXIgZGlmZXJlbnRlcyBhYm9yZGFnZW5zIGUgYXZhbGlhciBvcyByZXN1bHRhZG9zIHBhcmEgZW5jb250cmFyIGEgbWVsaG9yIHNvbHXDp8OjbyBwYXJhIG8gc2V1IGNhc28uCgojIyBQZXJndW50YSA0OiBGdW7Dp8OjbyBkZSBkZXRlY8Onw6NvIG1haW9yIHF1ZSAxIGVtIGFsZ3VtYXMgZGlzdMOibmNpYXMKClNlIGEgZnVuw6fDo28gZGUgZGV0ZWPDp8OjbyBlc3TDoSBhcHJlc2VudGFuZG8gdmFsb3JlcyBtYWlvcmVzIHF1ZSB1bSBlbSBhbGd1bWFzIGRpc3TDom5jaWFzLCBpc3NvIHBvZGUgaW5kaWNhciB1bSBwcm9ibGVtYSBubyBhanVzdGUgZG9zIG1vZGVsb3MgZGUgYW1vc3RyYWdlbSBwb3IgZGlzdMOibmNpYS4gQXF1aSBlc3TDo28gYWxndW1hcyBzdWdlc3TDtWVzIHBhcmEgcmVzb2x2ZXIgZXNzZSBwcm9ibGVtYToKCjEuIFZlcmlmaXF1ZSBvcyBkYWRvczogVmVyaWZpcXVlIHNlIG9zIHNldXMgZGFkb3MgZXN0w6NvIGNvcnJldG9zIGUgc2UgbsOjbyBow6EgZXJyb3MgbmEgcHJlcGFyYcOnw6NvIG91IHByb2Nlc3NhbWVudG8gZG9zIG1lc21vcy4gRXJyb3Mgbm9zIGRhZG9zIHBvZGVtIGxldmFyIGEgcmVzdWx0YWRvcyBpbmVzcGVyYWRvcyBuYSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvLiBWZXJpZmlxdWUgdGFtYsOpbSBzZSBuw6NvIGjDoSBwb250b3MgZHVwbGljYWRvcyBvdSBkYWRvcyBhdXNlbnRlcyBxdWUgcG9zc2FtIGFmZXRhciBvIGFqdXN0ZSBkbyBtb2RlbG8uCgoyLiBWZXJpZmlxdWUgYSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvOiBSZXZpc2UgYSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvIHV0aWxpemFkYSBubyBtb2RlbG8uIFZlcmlmaXF1ZSBzZSBhIGZ1bsOnw6NvIGVzdMOhIGNvcnJldGFtZW50ZSBlc3BlY2lmaWNhZGEgZSBzZSBlc3TDoSBzZW5kbyBhcGxpY2FkYSBjb3JyZXRhbWVudGUgYW9zIGRhZG9zLiBDZXJ0aWZpcXVlLXNlIGRlIHF1ZSBuw6NvIGjDoSBlcnJvcyBkZSBwcm9ncmFtYcOnw6NvIG91IGNvbmZpZ3VyYcOnw6NvIHF1ZSBlc3RlamFtIGNhdXNhbmRvIHZhbG9yZXMgbWFpb3JlcyBxdWUgdW0gbmEgZnVuw6fDo28gZGUgZGV0ZWPDp8Ojby4KCjMuIEFqdXN0ZSBkZSBwYXLDom1ldHJvczogRXhwZXJpbWVudGUgYWp1c3RhciBvcyBwYXLDom1ldHJvcyBkbyBtb2RlbG8gZGUgYW1vc3RyYWdlbSBwb3IgZGlzdMOibmNpYS4gUG9yIGV4ZW1wbG8sIHZvY8OqIHBvZGUgYWx0ZXJhciBvIHZhbG9yIGRvIHJhaW8gZGUgYnVzY2EgKHNlYXJjaCByYWRpdXMpIG91IG8gbsO6bWVybyBtw61uaW1vIGRlIHZpemluaG9zIG5lY2Vzc8OhcmlvcyBwYXJhIGRldGVjw6fDo28uIFBlcXVlbmFzIGFsdGVyYcOnw7VlcyBuZXNzZXMgcGFyw6JtZXRyb3MgcG9kZW0gYWZldGFyIGEgZnVuw6fDo28gZGUgZGV0ZWPDp8OjbyBlIGV2aXRhciBxdWUgZWxhIGFwcmVzZW50ZSB2YWxvcmVzIG1haW9yZXMgcXVlIHVtLgoKNC4gTm9ybWFsaXphw6fDo28gZG9zIGRhZG9zOiBDb25zaWRlcmUgbm9ybWFsaXphciBvcyBzZXVzIGRhZG9zIGFudGVzIGRlIGFqdXN0YXIgbyBtb2RlbG8uIEEgbm9ybWFsaXphw6fDo28gZG9zIGRhZG9zIHBhcmEgdW1hIGVzY2FsYSBlc3BlY8OtZmljYSwgY29tbyBhIGVzY2FsYSBbMCwgMV0sIHBvZGUgYWp1ZGFyIGEgZXZpdGFyIHZhbG9yZXMgbWFpb3JlcyBxdWUgdW0gbmEgZnVuw6fDo28gZGUgZGV0ZWPDp8Ojby4gSXNzbyBwb2RlIHNlciBlc3BlY2lhbG1lbnRlIMO6dGlsIHNlIG9zIHNldXMgZGFkb3MgcG9zc3XDrXJlbSBkaWZlcmVudGVzIG9yZGVucyBkZSBncmFuZGV6YS4KCjUuIEV4cGxvcmFyIG91dHJhcyBmdW7Dp8O1ZXMgZGUgZGV0ZWPDp8OjbzogU2UgYSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvIGF0dWFsIGVzdGl2ZXIgYXByZXNlbnRhbmRvIHByb2JsZW1hcywgdm9jw6ogcG9kZSBjb25zaWRlcmFyIHV0aWxpemFyIG91dHJhcyBmdW7Dp8O1ZXMgZGUgZGV0ZWPDp8OjbyBkaXNwb27DrXZlaXMgbm8gcGFjb3RlIERpc3RhbmNlIG91IGVtIG91dHJvcyBwYWNvdGVzLiBFeHBlcmltZW50ZSBkaWZlcmVudGVzIGZ1bsOnw7VlcyBwYXJhIGVuY29udHJhciBhcXVlbGEgcXVlIG1lbGhvciBzZSBhanVzdGEgYW9zIHNldXMgZGFkb3MgZSBldml0YSB2YWxvcmVzIG1haW9yZXMgcXVlIHVtLgoKNi4gVmVyaWZpcXVlIGEgZG9jdW1lbnRhw6fDo28gZSByZWN1cnNvcyBkbyBwYWNvdGU6IENvbnN1bHRlIGEgZG9jdW1lbnRhw6fDo28gZG8gcGFjb3RlIERpc3RhbmNlIGUgb3MgcmVjdXJzb3MgZGlzcG9uw612ZWlzIHBhcmEgb2J0ZXIgaW5mb3JtYcOnw7VlcyBlc3BlY8OtZmljYXMgc29icmUgcHJvYmxlbWFzIHJlbGFjaW9uYWRvcyDDoCBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvIGUgcG9zc8OtdmVpcyBzb2x1w6fDtWVzLiBGw7NydW5zIGRlIGRpc2N1c3PDo28gb3UgZ3J1cG9zIGRlIHVzdcOhcmlvcyByZWxhY2lvbmFkb3MgYW8gcGFjb3RlIHRhbWLDqW0gcG9kZW0gc2VyIMO6dGVpcyBwYXJhIG9idGVyIHN1cG9ydGUgZSBvcmllbnRhw6fDo28uCgpMZW1icmUtc2UgZGUgcXVlIMOpIGltcG9ydGFudGUgaW52ZXN0aWdhciBhIGNhdXNhIHJhaXogZG8gcHJvYmxlbWEgZSBpdGVyYXIgZW0gZGlmZXJlbnRlcyBhYm9yZGFnZW5zIGF0w6kgZW5jb250cmFyIHVtYSBzb2x1w6fDo28gYWRlcXVhZGEgcGFyYSBvIHNldSBjYXNvIGVzcGVjw61maWNvLgoKIyBQcmltZWlyYSBlc3DDqWNpZSBtb2RlbG8gCgojIyAqU2FndWludXMgbWlkYXMqIG5vICoqUGFybmEgTW9udGFuaGFzIGRvIFR1bXVjdW1hcXVlKioKCiMjIyBDYXJyZWdhciBkYWRvcwoKYGBge3J9CnNhZ3VpX21vbnRfdHVtdWMgPC0gdHJhbnNmb3JtYXJfcGFyYV9kaXN0YW5jZVJfY292YXJpYXZlaXMoKSB8PiAKICBmaWx0ZXIoCiAgICBSZWdpb24uTGFiZWwgPT0gIlBhcm5hIE1vbnRhbmhhcyBkbyBUdW11Y3VtYXF1ZSIsCiAgICBzcF9uYW1lID09ICJTYWd1aW51cyBtaWRhcyIKICApIHw+IAogIGRyb3BfbmEoZGlzdGFuY2UpCmBgYAoKIyMjIERpc3RyaWJ1acOnw6NvIGRhcyBkaXN0w6JuY2lhcyBwZXJwZW5kaWN1bGFyZXMKCmBgYHtyfQpzYWd1aV9tb250X3R1bXVjIHw+IAogIHBsb3Rhcl9kaXN0cmlidWljYW9fZGlzdGFuY2lhX2ludGVyYXRpdm8oKQpgYGAKCiMjIyBBanVzdGFuZG8gbW9kZWxvIGRpc3RhbmNlIGNvbSBmdW7Dp8OjbyBkZSBkZXRlY8Onw6NvIEhhbGYtTm9ybWFsIGUgZGlzdGFuY2lhIGRlIHRydW5jYW1lbnRvIDEwCgpgYGB7cn0Kc2FndWlfbW9udF90dW11Y19obiA8LSBzYWd1aV9tb250X3R1bXVjIHw+IAogIGFqdXN0ZV9tb2RlbG9zX2Rpc3RhbmNlX2huKHRydW5jYW1lbnRvID0gMTApCmBgYAoKIyMjIEFqdXN0YW5kbyBtb2RlbG8gZGlzdGFuY2UgY29tIGZ1bsOnw6NvIGRlIGRldGVjw6fDo28gSGF6YXJkLXJhdGUgZSBkaXN0YW5jaWEgZGUgdHJ1bmNhbWVudG8gMTAKCmBgYHtyfQpzYWd1aV9tb250X3R1bXVjX2hyIDwtIHNhZ3VpX21vbnRfdHVtdWMgfD4gCiAgYWp1c3RlX21vZGVsb3NfZGlzdGFuY2VfaHIodHJ1bmNhbWVudG8gPSAxMCkKYGBgCiMjIyBQbG90IGRvcyBtb2RlbG9zCgpgYGB7cn0Kc2FndWlfbW9udF90dW11Y19obiB8PiAKICBwdXJycjo6bWFwKFwoLngpIHBsb3QoLngpKSAKYGBgCgpgYGB7cn0Kc2FndWlfbW9udF90dW11Y19ociB8PiAKICBwdXJycjo6bWFwKFwoLngpIHBsb3QoLngpKSAKYGBgCgojIyMgU2VsZcOnw6NvIGRlIG1vZGVsb3MKCmBgYHtyfQpzdW1tYXJpemVfZHNfbW9kZWxzKAogIHNhZ3VpX21vbnRfdHVtdWNfaG4kYFNlbSB0ZXJtb2AsCiAgc2FndWlfbW9udF90dW11Y19obiRDb3NzZW5vLAogIHNhZ3VpX21vbnRfdHVtdWNfaG4kYEhlcm1pdGUgcG9saW5vbWlhbGAsCiAgc2FndWlfbW9udF90dW11Y19ociRgU2VtIHRlcm1vYCwKICBzYWd1aV9tb250X3R1bXVjX2hyJENvc3Nlbm8sCiAgc2FndWlfbW9udF90dW11Y19ociRgUG9saW5vbWlhbCBzaW1wbGVzYAopCmBgYAoKIyMjIFRlc3RlIGRlIGJvbmRhZGUgZGUgYWp1c3RlCgpgYGB7cn0Kc2FndWlfbW9udF90dW11Y19obiB8PiAKICBwdXJycjo6bWFwKFwoLngpIGdvZl9kcyhtb2RlbCA9IC54KSkKYGBgCgpgYGB7cn0Kc2FndWlfbW9udF90dW11Y19ociB8PiAKICBwdXJycjo6bWFwKFwoLngpIGdvZl9kcyhtb2RlbCA9IC54KSkKYGBgCgojIyMgRXN0aW1hbmRvIGEgYWJ1bmRhbmNpYQoKYGBge3J9CiMgw6FyZWEgZGUgZXN0dWRvLCB0YW1hbmhvIGRhIMOhcmVhIGRlIGVzdHVkbywgYXJlYSBjb2JlcnRhIHBlbG8gZXNmb3LDp28gYW1vc3RyYWwsIGVzZm9yw6dvIGFtb3N0cmFsIGVtIG1ldHJvcywgbsO6bWVybyBkZSBkZXRlY8Onw7VlcywgbsO6bWVybyBkZSB0cmFuc2VjdG9zIChlYSksIHRheGEgZGUgZW5jb250cm8sIGNvZWZpY2llbnRlIGRlIHZhcmlhw6fDo28gZGEgdGF4YSBkZSBlbmNvbnRybyAgCnNhZ3VpX21vbnRfdHVtdWNfaG4kYFNlbSB0ZXJtb2AkZGh0JGluZGl2aWR1YWxzJHN1bW1hcnlbMTo5XQpgYGAKCmBgYHtyfQojIMOhcmVhIGRlIGVzdHVkbywgdGFtYW5obyBkYSDDoXJlYSBkZSBlc3R1ZG8sIHRyaWxoYXMgb3UgZXN0YcOnw7VlcyBhbW9zdHJhaXMsIGVzZm9yw6dvIHRvdGFsIGVtIGNhZGEgdHJpbGhhLCBhYnVuZMOibmNpYSBlc3RpbWFkYSBlbSBjYWRhIGVzdGHDp8OjbyBhbW9zdHJhbCwgbsO6bWVybyBkZSBkZXRlY8Onw7VlcyBlbSBjYWRhIGVzdGHDp8OjbyBhbW9zdHJhbCwgw6FyZWEgdG90YWwgYW1vc3RyYWRhCnNhZ3VpX21vbnRfdHVtdWNfaG4kYFNlbSB0ZXJtb2AkZGh0JGluZGl2aWR1YWxzJE5oYXQuYnkuc2FtcGxlWzE6OF0KYGBgCgpgYGB7cn0KIyB0b3RhbCwgZGVuc2lkYWRlIGVzdGltYWRhLCBlcnJvIHBhZHLDo28gZGEgZGVuc2lkYWRlIGRlc3RpbWFkYSwgY29lZmljaWVudGUgZGUgdmFyaWHDp8OjbyBkYSBkZW5zaWRhZGUgZGVzdGltYWRhLCBpbnRlcnZhbG8gZGUgY29uZmlhbsOnYSBpbmZlcmlvciBlIHN1cGVyaW9yIGRvIGNvZWZpY2llbnRlIGRlIHZhcmlhw6fDo28sIGdydWFzIGRlIGxpYmVyZGFkZQpzYWd1aV9tb250X3R1bXVjX2huJGBTZW0gdGVybW9gJGRodCRpbmRpdmlkdWFscyRECgpgYGAKCmBgYHtyfQojIMOhcmVhIGRlIGVzdHVkbywgdGFtYW5obyBkYSDDoXJlYSBkZSBlc3R1ZG8sIGFyZWEgY29iZXJ0YSBwZWxvIGVzZm9yw6dvIGFtb3N0cmFsLCBlc2ZvcsOnbyBhbW9zdHJhbCBlbSBtZXRyb3MsIG7Dum1lcm8gZGUgZGV0ZWPDp8O1ZXMsIG7Dum1lcm8gZGUgdHJhbnNlY3RvcyAoZWEpLCB0YXhhIGRlIGVuY29udHJvLCBjb2VmaWNpZW50ZSBkZSB2YXJpYcOnw6NvIGRhIHRheGEgZGUgZW5jb250cm8gIApzYWd1aV9tb250X3R1bXVjX2hyJGBTZW0gdGVybW9gJGRodCRpbmRpdmlkdWFscyRzdW1tYXJ5WzE6OV0KYGBgCgpgYGB7cn0KIyDDoXJlYSBkZSBlc3R1ZG8sIHRhbWFuaG8gZGEgw6FyZWEgZGUgZXN0dWRvLCB0cmlsaGFzIG91IGVzdGHDp8O1ZXMgYW1vc3RyYWlzLCBlc2ZvcsOnbyB0b3RhbCBlbSBjYWRhIHRyaWxoYSwgYWJ1bmTDom5jaWEgZXN0aW1hZGEgZW0gY2FkYSBlc3Rhw6fDo28gYW1vc3RyYWwsIG7Dum1lcm8gZGUgZGV0ZWPDp8O1ZXMgZW0gY2FkYSBlc3Rhw6fDo28gYW1vc3RyYWwsIMOhcmVhIHRvdGFsIGFtb3N0cmFkYQpzYWd1aV9tb250X3R1bXVjX2hyJGBTZW0gdGVybW9gJGRodCRpbmRpdmlkdWFscyROaGF0LmJ5LnNhbXBsZVsxOjhdCmBgYApgYGB7cn0KKDEyNS44ICsgNjcuNiArIDI0MC44KS80ZSswNwpgYGAKCgpgYGB7cn0KIyB0b3RhbCwgZGVuc2lkYWRlIGVzdGltYWRhLCBlcnJvIHBhZHLDo28gZGEgZGVuc2lkYWRlIGRlc3RpbWFkYSwgY29lZmljaWVudGUgZGUgdmFyaWHDp8OjbyBkYSBkZW5zaWRhZGUgZGVzdGltYWRhLCBpbnRlcnZhbG8gZGUgY29uZmlhbsOnYSBpbmZlcmlvciBlIHN1cGVyaW9yIGRvIGNvZWZpY2llbnRlIGRlIHZhcmlhw6fDo28sIGdydWFzIGRlIGxpYmVyZGFkZQpzYWd1aV9tb250X3R1bXVjX2hyJGBTZW0gdGVybW9gJGRodCRpbmRpdmlkdWFscyRECgpgYGAKCiMgVGVudGF0aXZhIGRlIHJvZGFyIG8gZHNpdGFuY2UgcGFyYSBtYWlzIGRlIHVtYSBlc3DDqWNpZSBhbyBkZSB1bWEgc8OzIHZlegoKYGBge3J9CmRhZG9zX2VudHJlXzYwXzEzMCA8LSB0cmFuc2Zvcm1hcl9wYXJhX2Rpc3RhbmNlUl9jb3ZhcmlhdmVpcygpIHw+IAogIGZpbHRlcigKICAgIGRpc3RhbmNlID4gNjAsCiAgICBkaXN0YW5jZSA8IDEzMAogICkgfD4gCiAgZHJvcF9uYShkaXN0YW5jZSkKYGBgCgpgYGB7cn0KZGFkb3NfZW50cmVfNjBfMTMwX2FuaW5oYWRvX2VzcGVjaWUgPC0gZGFkb3NfZW50cmVfNjBfMTMwIHw+IAogIG5lc3Qoc3BfbmFtZSkKYGBgCgo=